Merge lp:~m-a-uchida/maus/GlobalDevelopment into lp:maus

Proposed by Melissa Uchida
Status: Merged
Merged at revision: 730
Proposed branch: lp:~m-a-uchida/maus/GlobalDevelopment
Merge into: lp:maus
Diff against target: 1743 lines (+881/-368)
21 files modified
doc/doc_src/maus_user_guide.tex (+1/-1)
doc/doc_src/reconstruction/globalds/globalds.tex (+91/-0)
src/common_cpp/Recon/Global/TrackMatching.cc (+3/-3)
src/common_cpp/Recon/SciFi/PatternRecognition.cc (+38/-5)
src/common_cpp/Recon/SciFi/PatternRecognition.hh (+15/-2)
src/common_cpp/Recon/SciFi/RootFitter.cc (+104/-0)
src/common_cpp/Recon/SciFi/RootFitter.hh (+57/-0)
src/common_cpp/Recon/SciFi/SimpleCircle.cc (+8/-2)
src/common_cpp/Recon/SciFi/SimpleCircle.hh (+9/-4)
src/common_py/ConfigurationDefaults.py (+2/-0)
tests/cpp_unit/Recon/SciFi/PatternRecognitionTest.cc (+284/-136)
tests/cpp_unit/Recon/SciFi/SimpleCircleTest.cc (+9/-2)
tests/py_unit/test_maus_cpp/test_optics/test_optics_model.py (+162/-9)
tests/py_unit/test_maus_cpp/test_optics/test_optics_model_subprocess (+0/-192)
tests/unit_tests.bash (+8/-3)
third_party/bash/21root.bash (+11/-4)
third_party/bash/47cdb_cpp.bash (+2/-2)
third_party/build_all.bash (+2/-2)
third_party/source/cdb.client.api-cpp.v1.0.3.tgz.md5 (+0/-1)
third_party/source/cdb.client.api-cpp.v1.0.4.tgz.md5 (+1/-0)
third_party/source/gcc6.patch (+74/-0)
To merge this branch: bzr merge lp:~m-a-uchida/maus/GlobalDevelopment
Reviewer Review Type Date Requested Status
MAUS release managers Pending
Review via email: mp+325323@code.launchpad.net

Description of the change

Just a very small change to track matching to improve the user experience, putting exceptions into debug mode.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/doc_src/maus_user_guide.tex'
2--- doc/doc_src/maus_user_guide.tex 2017-05-15 14:17:05 +0000
3+++ doc/doc_src/maus_user_guide.tex 2017-06-08 17:10:31 +0000
4@@ -60,7 +60,7 @@
5
6 \input{reconstruction/globaltrackmatching/globaltrackmatching.tex}
7 \input{reconstruction/globalpid/globalpid.tex}
8-% \input{reconstruction/globalds/globalds.tex}
9+\input{reconstruction/globalds/globalds.tex}
10
11 \input{envelope_tool} % envelope utility - could be an appendix
12
13
14=== added directory 'doc/doc_src/reconstruction/globalds'
15=== added file 'doc/doc_src/reconstruction/globalds/globalds.tex'
16--- doc/doc_src/reconstruction/globalds/globalds.tex 1970-01-01 00:00:00 +0000
17+++ doc/doc_src/reconstruction/globalds/globalds.tex 2017-06-08 17:10:31 +0000
18@@ -0,0 +1,91 @@
19+\chapter{Accessing Global Tracks}
20+\label{chapter:globalds}
21+
22+The global datastructure is set up so that the state of tracks at any point in the processing chain, import,
23+track matching, pid, and track fitting, can easily be accessed in order to understand where a given track
24+came from and what lead to its current state.
25+
26+To achieve this, tracks are packaged together in PrimaryChain objects which retain copies of the
27+tracks at every step along the way. There will generally be one primary chain for every tracker track that
28+has been matched to at least one additional detector, plus possible through primary chains for tracks
29+that have been matched through the absorber.
30+
31+\section{The PrimaryChain Object}\label{sec:primarychain}
32+
33+A primary chain (\texttt{MAUS::DataStructure::Global::PrimaryChain}) has a number of member functions
34+for accessing parameters describing the chain as well as the variety of tracks that are contained in it:
35+
36+\begin{description}
37+ \item [get\_chain\_type()] A chain can hold either upstream tracks, downstream tracks, or through tracks. The chain type is an enumerator with the following values
38+ \begin{description}
39+ \item [kNoChainType] Used for initialization only
40+ \item [kUS] A chain containing upstream tracks. This value furthermore implies that a track in the chain has been matched into a through chain.
41+ \item [kDS] A chain containing downstream tracks. This value furthermore implies that a track in the chain has been matched into a through chain.
42+ \item [kUSOrphan] A chain containing upstream tracks none of which has been matched into a through track
43+ \item [kDSOrphan] A chain containing downstream tracks none of which has been matched into a through track
44+ \item [kThrough] A chain containing through tracks. It will also reference daughter upstream and downstream chains
45+ \end{description}
46+ \item [get\_chain\_multiplicity] This is only a meaningful property for through chains. It describes whether this and another through chain are mutually exclusive
47+ because they share daughter chains, for example if the same upstream track has been matched to multiple downstream tracks. The possible values of the enumerator are
48+ \begin{description}
49+ \item [kUnique] This chain does not share daughter chains with any other through chains
50+ \item [kMultipleUS] This chain shares an upstream chain with at least one other through chain
51+ \item [kMultipleDS] This chain shares a downstream chain with at least one other through chain
52+ \item [kMultipleBoth] This chain shares both its upstream and downstream chains with other through chains
53+ \end{description}
54+ Note that constellations are possible where e.g. there are 3 chains, one of type \texttt{kMultipleUS}, one of type \texttt{kMultipleDS},
55+ and the last of type \texttt{kMultipleBoth}.
56+ \item [get\_mapper\_name()] The name of the mapper that last modified this primary chain object.
57+ \item [GetUSDaughter()] For a through chain returns the upstream daughter chain.
58+ \item [GetDSDaughter()] For a through chain returns the downstream daughter chain.
59+ \item [GetMatchedTracks()] Returns a vector of all matched tracks for this chain. There is not a single matched track since as described in section ref{sec:tmprocess},
60+ tracks for all feasible PID hypotheses have to be created.
61+ \item [GetPIDTrack()] Returns the PID'd track (if one exists in the chain).
62+ \item [GetFittedTrack()] Returns the fitted track (if one exists in the chain).
63+\end{description}
64+
65+Note that the global track object also holds references to constituent tracks, so there are two different
66+ways one could obtain upstream and downstream tracks from a through primary chain. For example to obtain PID'd tracks:
67+\begin{verbatim}
68+through_chain->GetPIDTrack()->GetConstituentTracks()
69+\end{verbatim}
70+or
71+\begin{verbatim}
72+through_chain->GetUSDaughter()->GetPIDTrack()
73+through_chain->GetDSDaughter()->GetPIDTrack()
74+\end{verbatim}
75+
76+\subsection{Identifying Decay Candidates}\label{subsec:decay_candidates}
77+
78+Primary chains also allow identifying events that may contain a $\pi \rightarrow \mu$ or $\mu \rightarrow e$ decay. If an upstream
79+and downstream track come out of Particle ID with different PIDs, no PID'd through track can be created, so an existing through
80+chain will return NULL from \texttt{through\_chain->GetPIDTrack()}. In this case, a decay candidate can be identified e.g. by testing that
81+\begin{verbatim}
82+through_chain->GetUSDaughter()->GetPIDTrack()->get_pid()
83+ == MAUS::DataStructure::Global::kPiPlus
84+\end{verbatim}
85+and
86+\begin{verbatim}
87+through_chain->GetDSDaughter()->GetPIDTrack()->get_pid()
88+ == MAUS::DataStructure::Global::kMuPlus
89+\end{verbatim}
90+
91+Additional candidates could be identified from orphan chains, but caution is advised, as there is a good chance these might be from different particles rather than decays.
92+
93+\section{Tracks and Space Points from Local Reconstruction}\label{sec:lr_tracks_spacepoints}
94+
95+While tracks and space points from the local reconstruction which have ended up in matched tracks can be accessed as constituent tracks of matched tracks and
96+as space points linked to by the track points in matched tracks, there might be a need to access all tracks and spacepoints from local reconstruction,
97+including those that were not successfully matched. Since they can't be associated with a primary chain, they can be accessed direcly from the global event via
98+\begin{verbatim}
99+std::vector<MAUS::DataStructure::Global::Track*> GetLRTracks()
100+std::vector<MAUS::DataStructure::Global::Track*>
101+ GetLRTracks(MAUS::DataStructure::Global::DetectorPoint detector)
102+\end{verbatim}
103+and
104+\begin{verbatim}
105+std::vector<MAUS::DataStructure::Global::SpacePoint*> GetLRSpacePoints()
106+std::vector<MAUS::DataStructure::Global::SpacePoint*>
107+ GetLRSpacePoints(MAUS::DataStructure::Global::DetectorPoint detector)
108+\end{verbatim}
109+where the optional argument detector allows specifying from which detectors tracks or space points should be retrieved.
110
111=== modified file 'doc/maus_user_guide.pdf'
112Binary files doc/maus_user_guide.pdf 2017-05-15 14:17:05 +0000 and doc/maus_user_guide.pdf 2017-06-08 17:10:31 +0000 differ
113=== modified file 'src/common_cpp/Recon/Global/TrackMatching.cc'
114--- src/common_cpp/Recon/Global/TrackMatching.cc 2017-03-17 12:44:22 +0000
115+++ src/common_cpp/Recon/Global/TrackMatching.cc 2017-06-08 17:10:31 +0000
116@@ -503,7 +503,7 @@
117 // If there are multiple matches, this checks if they could have been from the same particle
118 AddIfConsistent(temp_spacepoints, hypothesis_track);
119 } catch (Exceptions::Exception exc) {
120- Squeak::mout(Squeak::error) << exc.what() << std::endl;
121+ Squeak::mout(Squeak::debug) << exc.what() << std::endl;
122 }
123 }
124 }
125@@ -528,7 +528,7 @@
126 GlobalTools::propagate(x_in, tof1_z - 25.0, field, _max_step_size, pid,
127 _energy_loss);
128 } catch (Exceptions::Exception exc) {
129- Squeak::mout(Squeak::error) << exc.what() << std::endl;
130+ Squeak::mout(Squeak::debug) << exc.what() << std::endl;
131 }
132 // Calculate the distance to TOF0 and the approximate distance the particle travelled
133 double z_distance = tof1_z - spacepoints.at(0)->get_position().Z();
134@@ -626,7 +626,7 @@
135 << x_in[2] - first_hit_pos.Y() << std::endl;
136 }
137 } catch (Exceptions::Exception exc) {
138- Squeak::mout(Squeak::error) << exc.what() << std::endl;
139+ Squeak::mout(Squeak::debug) << exc.what() << std::endl;
140 }
141 if (matched) {
142 break;
143
144=== modified file 'src/common_cpp/Recon/SciFi/PatternRecognition.cc'
145--- src/common_cpp/Recon/SciFi/PatternRecognition.cc 2017-05-12 14:13:30 +0000
146+++ src/common_cpp/Recon/SciFi/PatternRecognition.cc 2017-06-08 17:10:31 +0000
147@@ -37,6 +37,8 @@
148
149 // MAUS headers
150 #include "src/common_cpp/Recon/SciFi/PatternRecognition.hh"
151+#include "src/common_cpp/Recon/SciFi/LeastSquaresFitter.hh"
152+#include "src/common_cpp/Recon/SciFi/RootFitter.hh"
153 #include "src/common_cpp/DataStructure/ThreeVector.hh"
154 #include "src/common_cpp/Utils/Globals.hh"
155 #include "src/common_cpp/Globals/GlobalsManager.hh"
156@@ -67,6 +69,8 @@
157 _down_helical_pr_on(true),
158 _sp_search_on(false),
159 _s_error_method(0),
160+ _line_fitter(0),
161+ _circle_fitter(0),
162 _verb(0),
163 _n_trackers(2),
164 _n_stations(5),
165@@ -105,6 +109,8 @@
166 _down_helical_pr_on = true;
167 _sp_search_on = false;
168 _s_error_method = 0;
169+ _line_fitter = 0;
170+ _circle_fitter = 0;
171 _verb = 0;
172 _n_trackers = 2;
173 _n_stations = 5;
174@@ -165,6 +171,8 @@
175 Json::Value *json = Globals::GetConfigurationCards();
176 _sp_search_on = (*json)["SciFiPatRecMissingSpSearchOn"].asBool();
177 _s_error_method = (*json)["SciFiPatRecSErrorMethod"].asInt();
178+ _line_fitter = (*json)["SciFiPatRecLineFitter"].asInt();
179+ _circle_fitter = (*json)["SciFiPatRecCircleFitter"].asInt();
180 _verb = (*json)["SciFiPatRecVerbosity"].asInt();
181 _n_trackers = (*json)["SciFinTrackers"].asInt();
182 _n_stations = (*json)["SciFinStations"].asInt();
183@@ -628,8 +636,13 @@
184 // Fit track
185 SimpleLine line_x, line_y;
186 TMatrixD cov_x(2, 2), cov_y(2, 2);
187- LeastSquaresFitter::linear_fit(z, x, x_err, line_x, cov_x);
188- LeastSquaresFitter::linear_fit(z, y, y_err, line_y, cov_y);
189+ if (_line_fitter == 0) { // Custom LSQ fitter
190+ LeastSquaresFitter::linear_fit(z, x, x_err, line_x, cov_x);
191+ LeastSquaresFitter::linear_fit(z, y, y_err, line_y, cov_y);
192+ } else if (_line_fitter == 1) { // ROOT based linear fitter
193+ RootFitter::FitLineLinear(z, x, x_err, line_x, cov_x);
194+ RootFitter::FitLineLinear(z, y, y_err, line_y, cov_y);
195+ }
196
197 // Squash the covariances of each fit into one vector
198 std::vector<double> covariance;
199@@ -754,8 +767,24 @@
200 TMatrixD cov_circle(3, 3); // The covariance matrix for the circle parameters alpha, beta, gamma
201 double s1to4_error = _sd_1to4 * _circle_error_w;
202 double s5_error = _sd_5 * _circle_error_w;
203- bool good_radius = LeastSquaresFitter::circle_fit(s1to4_error, s5_error, _R_res_cut,
204- spnts, c_trial, cov_circle);
205+
206+ bool good_radius = false;
207+ if (_circle_fitter == 0) {
208+ // With a custom linear least squares fit
209+ good_radius = LeastSquaresFitter::circle_fit(s1to4_error, s5_error, _R_res_cut,
210+ spnts, c_trial, cov_circle);
211+ } else if (_circle_fitter == 1) {
212+ // With a ROOT MINUIT based fitter
213+ std::vector<double> x;
214+ std::vector<double> y;
215+ for (auto sp : spnts) {
216+ x.push_back(sp->get_position().x());
217+ y.push_back(sp->get_position().y());
218+ }
219+ good_radius = RootFitter::FitCircleMinuit(x, y, c_trial, cov_circle);
220+ if (c_trial.get_R() > _R_res_cut)
221+ good_radius = false;
222+ }
223
224 // If the radius calculated is too large or chisq fails, return NULL
225 if ( !good_radius || !( c_trial.get_chisq() / ( (2*n_points) - 3 ) < _circle_chisq_cut ) ) {
226@@ -884,7 +913,11 @@
227 }
228
229 // Fit ds and dz to a straight line, to get the gradient, which equals ds/dz
230- LeastSquaresFitter::linear_fit(z_i, s_i, sigma_s, line_sz, cov_sz);
231+ if (_line_fitter == 0) { // Custom LSQ fitter
232+ LeastSquaresFitter::linear_fit(z_i, s_i, sigma_s, line_sz, cov_sz);
233+ } else if (_line_fitter == 1) { // ROOT based linear fitter
234+ RootFitter::FitLineLinear(z_i, s_i, sigma_s, line_sz, cov_sz);
235+ }
236
237 // Check linear fit passes chisq test
238 if ( !(line_sz.get_chisq() / ( n_points - 2 ) < _sz_chisq_cut ) ) {
239
240=== modified file 'src/common_cpp/Recon/SciFi/PatternRecognition.hh'
241--- src/common_cpp/Recon/SciFi/PatternRecognition.hh 2017-05-12 14:13:30 +0000
242+++ src/common_cpp/Recon/SciFi/PatternRecognition.hh 2017-06-08 17:10:31 +0000
243@@ -40,7 +40,6 @@
244 #include "gtest/gtest_prod.h"
245
246 // MAUS headers
247-#include "src/common_cpp/Recon/SciFi/LeastSquaresFitter.hh"
248 #include "src/common_cpp/Recon/SciFi/SciFiTools.hh"
249 #include "src/common_cpp/Recon/SciFi/SimpleLine.hh"
250 #include "src/common_cpp/Recon/SciFi/SimpleCircle.hh"
251@@ -375,6 +374,18 @@
252 /** @brief Set the boolean controlling if we search for missed helical seed spacepoints */
253 void set_sp_search_on(bool sp_search_on) { _sp_search_on = sp_search_on; }
254
255+ /** @brief Return the line fit method */
256+ int get_line_fitter() { return _line_fitter; }
257+
258+ /** @brief Set line fit method */
259+ void set_line_fitter(int line_fitter) { _line_fitter = line_fitter; }
260+
261+ /** @brief Get the circle fit method */
262+ int get_circle_fitter() { return _circle_fitter; }
263+
264+ /** @brief Set circle fit method */
265+ void set_circle_fitter(int circle_fitter) { _circle_fitter = circle_fitter; }
266+
267 /** @brief Return the verbosity level */
268 bool get_verbosity() { return _verb; }
269
270@@ -420,6 +431,8 @@
271 bool _down_helical_pr_on; /** Downstream Helical pattern recogntion on or off */
272 bool _sp_search_on; /** Do we seach for seed spoints missed by helical fit? */
273 int _s_error_method; /** How to calc error on s, 0 = station res, 1 = error prop */
274+ int _line_fitter; /** Line fitter, 0 = custom lsq, 1 = ROOT */
275+ int _circle_fitter; /** Circle fitter, 0 = custom lsq, 1 = MINUIT */
276 int _verb; /** Verbosity: 0=little, 1=more couts */
277 int _n_trackers; /** Number of trackers */
278 int _n_stations; /** Number of stations per tracker */
279@@ -440,7 +453,7 @@
280 double _Pt_max; /** MeV/c max Pt for h tracks (given by R_max = 150mm) */
281 double _Pz_min; /** MeV/c min Pz for helical tracks (this is a guess) */
282 double _missing_sp_cut; /** Dist (mm) below which a missing spoint should be added to trk*/
283- // LeastSquaresFitter _lsq; /** The linear least squares fitting class instance */
284+
285 TFile* _rfile; /** A ROOT file pointer for dumping residuals to in debug mode */
286 TH1D* _hx; /** histo of x residuals taken during straight road cut stage */
287 TH1D* _hy; /** histo of y residuals taken during straight road cut stage */
288
289=== added file 'src/common_cpp/Recon/SciFi/RootFitter.cc'
290--- src/common_cpp/Recon/SciFi/RootFitter.cc 1970-01-01 00:00:00 +0000
291+++ src/common_cpp/Recon/SciFi/RootFitter.cc 2017-06-08 17:10:31 +0000
292@@ -0,0 +1,104 @@
293+/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
294+ *
295+ * MAUS is free software: you can redistribute it and/or modify
296+ * it under the terms of the GNU General Public License as published by
297+ * the Free Software Foundation, either version 3 of the License, or
298+ * (at your option) any later version.
299+ *
300+ * MAUS is distributed in the hope that it will be useful,
301+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
302+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303+ * GNU General Public License for more details.
304+ *
305+ * You should have received a copy of the GNU General Public License
306+ * along with MAUS. If not, see <http://www.gnu.org/licenses/>.
307+ *
308+ */
309+
310+// ROOT headers
311+#include "TLinearFitter.h"
312+#include "TMatrixTBase.h"
313+#include "TMath.h"
314+#include "Math/Functor.h"
315+#include "Fit/Fitter.h"
316+
317+// MAUS headers
318+#include "src/common_cpp/Recon/SciFi/RootFitter.hh"
319+
320+namespace RootFitter {
321+
322+bool FitLineLinear(const std::vector<double>& x, const std::vector<double>& y,
323+ const std::vector<double>& yerr, MAUS::SimpleLine& line, TMatrixD& cov_matrix) {
324+
325+ TLinearFitter lf(1);
326+ lf.SetFormula("pol1");
327+ // Have to copy data into new elements as AssignData wants non-const arguments for some reason
328+ std::vector<double> x1 = x;
329+ std::vector<double> y1 = y;
330+ std::vector<double> yerr1 = yerr;
331+ lf.AssignData(x.size(), 1, &x1[0], &y1[0], &yerr1[0]);
332+ lf.Eval();
333+
334+ TVectorD params;
335+ TVectorD errors;
336+ lf.GetParameters(params);
337+ lf.GetErrors(errors);
338+
339+ line.set_c(params[0]);
340+ line.set_m(params[1]);
341+ line.set_c_err(errors[0]);
342+ line.set_m_err(errors[1]);
343+ line.set_chisq(lf.GetChisquare());
344+ lf.GetCovarianceMatrix(cov_matrix);
345+
346+ return true;
347+}
348+
349+bool FitCircleMinuit(const std::vector<double>& x, const std::vector<double>& y,
350+ MAUS::SimpleCircle& circ, TMatrixD& cov_matrix) {
351+
352+ auto Chi2Function = [&x, &y](const double *par) {
353+ // Minimisation function computing the sum of squares of residuals
354+ // looping over the points
355+ double f = 0.0;
356+ for (size_t i = 0; i < x.size(); i++) {
357+ double u = x[i] - par[0];
358+ double v = y[i] - par[1];
359+ double dr = par[2] - std::sqrt(u*u+v*v);
360+ f += dr*dr;
361+ }
362+ return f;
363+ };
364+
365+ // Wrap chi2 function in a function object for the fit
366+ // 3 is the number of fit parameters (size of array par)
367+ ROOT::Math::Functor fcn(Chi2Function, 3);
368+ ROOT::Fit::Fitter fitter;
369+ double pStart[3] = {0, 0, 1};
370+ fitter.SetFCN(fcn, pStart);
371+ fitter.Config().ParSettings(0).SetName("x0");
372+ fitter.Config().ParSettings(1).SetName("y0");
373+ fitter.Config().ParSettings(2).SetName("R");
374+
375+ // do the fit
376+ bool ok = fitter.FitFCN();
377+ if (!ok) {
378+ return ok;
379+ }
380+ const ROOT::Fit::FitResult & result = fitter.Result();
381+ result.Print(std::cout);
382+
383+ // Create a circle object with the results
384+ circ = MAUS::SimpleCircle(result.Parameter(0), result.Parameter(1),
385+ result.Parameter(2));
386+ circ.set_x0_err(result.Error(0));
387+ circ.set_y0_err(result.Error(1));
388+ circ.set_R_err(result.Error(2));
389+ // circ.set_chisq(result.Chi2());
390+ circ.set_chisq(result.MinFcnValue());
391+ circ.set_pvalue(result.Prob());
392+ result.GetCovarianceMatrix(cov_matrix);
393+
394+ return true;
395+}
396+}
397
398=== added file 'src/common_cpp/Recon/SciFi/RootFitter.hh'
399--- src/common_cpp/Recon/SciFi/RootFitter.hh 1970-01-01 00:00:00 +0000
400+++ src/common_cpp/Recon/SciFi/RootFitter.hh 2017-06-08 17:10:31 +0000
401@@ -0,0 +1,57 @@
402+/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
403+ *
404+ * MAUS is free software: you can redistribute it and/or modify
405+ * it under the terms of the GNU General Public License as published by
406+ * the Free Software Foundation, either version 3 of the License, or
407+ * (at your option) any later version.
408+ *
409+ * MAUS is distributed in the hope that it will be useful,
410+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
411+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
412+ * GNU General Public License for more details.
413+ *
414+ * You should have received a copy of the GNU General Public License
415+ * along with MAUS. If not, see <http://www.gnu.org/licenses/>.
416+ *
417+ */
418+
419+#ifndef ROOTFITTER_HH
420+#define ROOTFITTER_HH
421+
422+// C++ headers
423+#include <vector>
424+
425+// ROOT headers
426+#include "TMatrixD.h"
427+
428+// MAUS headers
429+#include "src/common_cpp/Recon/SciFi/SimpleLine.hh"
430+#include "src/common_cpp/Recon/SciFi/SimpleCircle.hh"
431+
432+/** @namespace RootFitter
433+ *
434+ * ROOT fitting routines
435+ */
436+namespace RootFitter {
437+
438+/** @brief Fit a straight line using the ROOT TLinearFit class
439+ * @param[in] x x coordinates (the indepepndent variable)
440+ * @param[in] y y coordinates (the depepndent variable)
441+ * @param[in] yerr Errors on the y coordinates
442+ * @param[out] line The fit result including errors
443+ * @param[out] cov_matrix The 2*2 covariance matrix of the returned parameters
444+ */
445+bool FitLineLinear(const std::vector<double>& x, const std::vector<double>& y,
446+ const std::vector<double>& yerr, MAUS::SimpleLine& line, TMatrixD& cov_matrix);
447+
448+/** @brief Fit a circle using the ROOT MINUIT minimiser class
449+ * @param[in] x x coordinates (a dependent variable)
450+ * @param[in] y y coordinates (a depepndent variable)
451+ * @param[out] circ The fit result
452+ * @param[out] cov_matrix The 3*3 covariance matrix of the returned parameters
453+ */
454+bool FitCircleMinuit(const std::vector<double>& x, const std::vector<double>& y,
455+ MAUS::SimpleCircle& circ, TMatrixD& cov_matrix);
456+}
457+
458+#endif
459
460=== modified file 'src/common_cpp/Recon/SciFi/SimpleCircle.cc'
461--- src/common_cpp/Recon/SciFi/SimpleCircle.cc 2013-07-09 17:12:03 +0000
462+++ src/common_cpp/Recon/SciFi/SimpleCircle.cc 2017-06-08 17:10:31 +0000
463@@ -37,6 +37,7 @@
464 _kappa_err = 0.0;
465 _delta_R = 0.0;
466 _chisq = 0.0;
467+ _pvalue = 0.0;
468 }
469
470 SimpleCircle::SimpleCircle(double x0, double y0, double R) {
471@@ -56,12 +57,13 @@
472 _kappa_err = 0.0;
473 _delta_R = 0.0;
474 _chisq = 0.0;
475+ _pvalue = 0.0;
476 }
477
478 SimpleCircle::SimpleCircle(double x0, double x0_err, double y0, double y0_err, double R,
479 double R_err, double alpha, double alpha_err, double beta,
480 double beta_err, double gamma, double gamma_err, double kappa,
481- double kappa_err, double delta_R, double chisq) {
482+ double kappa_err, double delta_R, double chisq, double pvalue) {
483 _x0 = x0;
484 _x0_err = x0_err;
485 _y0 = y0;
486@@ -78,6 +80,7 @@
487 _kappa_err = kappa_err;
488 _delta_R = delta_R;
489 _chisq = chisq;
490+ _pvalue = pvalue;
491 }
492
493 // Destructor
494@@ -100,12 +103,14 @@
495 _kappa_err = 0.0;
496 _delta_R = 0.0;
497 _chisq = 0.0;
498+ _pvalue = 0.0;
499 }
500
501 void SimpleCircle::set_parameters(double x0, double x0_err, double y0, double y0_err,
502 double R, double R_err, double alpha, double alpha_err,
503 double beta, double beta_err, double gamma, double gamma_err,
504- double kappa, double kappa_err, double delta_R, double chisq) {
505+ double kappa, double kappa_err, double delta_R,
506+ double chisq, double pvalue) {
507 _x0 = x0;
508 _x0_err = x0_err;
509 _y0 = y0;
510@@ -122,6 +127,7 @@
511 _kappa_err = kappa_err;
512 _delta_R = delta_R;
513 _chisq = chisq;
514+ _pvalue = pvalue;
515 }
516
517 } // ~namespace MAUS
518
519=== modified file 'src/common_cpp/Recon/SciFi/SimpleCircle.hh'
520--- src/common_cpp/Recon/SciFi/SimpleCircle.hh 2013-07-09 17:12:03 +0000
521+++ src/common_cpp/Recon/SciFi/SimpleCircle.hh 2017-06-08 17:10:31 +0000
522@@ -33,9 +33,10 @@
523 SimpleCircle(double x0, double y0, double R);
524
525 /** Second parameter constructor */
526- SimpleCircle(double x0, double x0_err, double y0, double y0_err, double R, double R_err,
527- double alpha, double alpha_err, double beta, double beta_err, double gamma,
528- double gamma_err, double kappa, double kappa_err, double delta_R, double chisq);
529+ SimpleCircle(double x0, double x0_err, double y0, double y0_err, double R,
530+ double R_err, double alpha, double alpha_err, double beta,
531+ double beta_err, double gamma, double gamma_err, double kappa,
532+ double kappa_err, double delta_R, double chisq, double pvalue);
533
534 /** Destructor */
535 ~SimpleCircle(); // Default destructor
536@@ -57,6 +58,7 @@
537 double get_kappa_err() const { return _kappa_err; }
538
539 double get_chisq() const { return _chisq; }
540+ double get_pvalue() const { return _pvalue; }
541 double get_delta_R() const { return _delta_R; }
542
543 // Setters
544@@ -76,12 +78,14 @@
545 void set_kappa(double kappa) { _kappa = kappa; }
546 void set_kappa_err(double kappa_err) { _kappa_err = kappa_err; }
547 void set_chisq(double chisq) { _chisq = chisq; }
548+ void set_pvalue(double pvalue) { _pvalue = pvalue; }
549 void set_delta_R(double delta_R) { _delta_R = delta_R; }
550
551 void set_parameters(double x0, double x0_err, double y0, double y0_err,
552 double R, double R_err, double alpha, double alpha_err,
553 double beta, double beta_err, double gamma, double gamma_err,
554- double kappa, double kappa_err, double delta_R, double chisq);
555+ double kappa, double kappa_err, double delta_R,
556+ double chisq, double pvalue);
557
558 private:
559 double _x0;
560@@ -100,6 +104,7 @@
561 double _kappa_err;
562 double _delta_R;
563 double _chisq;
564+ double _pvalue;
565 };
566
567 } // ~namespace MAUS
568
569=== modified file 'src/common_py/ConfigurationDefaults.py'
570--- src/common_py/ConfigurationDefaults.py 2017-05-11 12:09:56 +0000
571+++ src/common_py/ConfigurationDefaults.py 2017-06-08 17:10:31 +0000
572@@ -303,6 +303,8 @@
573 SciFiPatRecMissingSpCut = 2 # Distance (mm) below which a missing spoint should added to a track
574 SciFiPatRecSErrorMethod = 0 # How to calc error on s, 0 = station res, 1 = error prop
575 SciFiPatRecVerbosity = 0 # The verbosity of the pat rec (0 - quiet, 1 - more)
576+SciFiPatRecLineFitter = 0 # Choose the patrec straight line fitter, 0 = custom lsq, 1 = ROOT
577+SciFiPatRecCircleFitter = 0 # Choose the patrec circle fitter, 0 = custom lsq, 1 = MINUIT
578 SciFiStraightRoadCut = 7.0 # The road cut in pat rec for straights (mm)
579 SciFiStraightChi2Cut = 50.0 # Chi^2 on pat rec straight track fit
580 SciFiRadiusResCut = 150.0 # Helix radius cut (mm) for pattern recognition
581
582=== modified file 'tests/cpp_unit/Recon/SciFi/PatternRecognitionTest.cc'
583--- tests/cpp_unit/Recon/SciFi/PatternRecognitionTest.cc 2017-05-02 16:26:10 +0000
584+++ tests/cpp_unit/Recon/SciFi/PatternRecognitionTest.cc 2017-06-08 17:10:31 +0000
585@@ -36,7 +36,7 @@
586 virtual void SetUp() {}
587 virtual void TearDown() {}
588
589- std::vector<SciFiSpacePoint*> set_up_spacepoints() {
590+ std::vector<SciFiSpacePoint*> set_up_single_track_spacepoints() {
591 SciFiSpacePoint *sp1 = new SciFiSpacePoint();
592 SciFiSpacePoint *sp2 = new SciFiSpacePoint();
593 SciFiSpacePoint *sp3 = new SciFiSpacePoint();
594@@ -87,6 +87,139 @@
595
596 return spnts;
597 }
598+
599+ std::vector<SciFiSpacePoint*> set_up_multiple_track_spacepoints() {
600+ // Here we use the npe just to keep track of which tracker and
601+ // track number each sp belongs to
602+ std::vector<SciFiSpacePoint*> spnts_t1_trk1;
603+ for ( size_t i = 0; i < 5; ++i ) {
604+ spnts_t1_trk1.push_back(new SciFiSpacePoint());
605+ spnts_t1_trk1[i]->set_tracker(0);
606+ spnts_t1_trk1[i]->set_station(5-i);
607+ spnts_t1_trk1[i]->set_used(false);
608+ spnts_t1_trk1[i]->set_npe(11);
609+ }
610+ std::vector<SciFiSpacePoint*> spnts_t1_trk2;
611+ for ( size_t i = 0; i < 5; ++i ) {
612+ spnts_t1_trk2.push_back(new SciFiSpacePoint());
613+ spnts_t1_trk2[i]->set_tracker(0);
614+ spnts_t1_trk2[i]->set_station(5-i);
615+ spnts_t1_trk2[i]->set_used(false);
616+ spnts_t1_trk2[i]->set_npe(12);
617+ }
618+ std::vector<SciFiSpacePoint*> spnts_t1_trk3;
619+ for ( size_t i = 0; i < 5; ++i ) {
620+ spnts_t1_trk3.push_back(new SciFiSpacePoint());
621+ spnts_t1_trk3[i]->set_tracker(0);
622+ spnts_t1_trk3[i]->set_station(5-i);
623+ spnts_t1_trk3[i]->set_used(false);
624+ spnts_t1_trk3[i]->set_npe(13);
625+ }
626+ std::vector<SciFiSpacePoint*> spnts_t1_trk4;
627+ for ( size_t i = 0; i < 5; ++i ) {
628+ spnts_t1_trk4.push_back(new SciFiSpacePoint());
629+ spnts_t1_trk4[i]->set_tracker(0);
630+ spnts_t1_trk4[i]->set_station(5-i);
631+ spnts_t1_trk4[i]->set_used(false);
632+ spnts_t1_trk4[i]->set_npe(14);
633+ }
634+
635+ std::vector<SciFiSpacePoint*> spnts_t2_trk1;
636+ for ( size_t i = 0; i < 5; ++i ) {
637+ spnts_t2_trk1.push_back(new SciFiSpacePoint());
638+ spnts_t2_trk1[i]->set_tracker(1);
639+ spnts_t2_trk1[i]->set_station(i+1);
640+ spnts_t2_trk1[i]->set_used(false);
641+ spnts_t2_trk1[i]->set_npe(21);
642+ }
643+ std::vector<SciFiSpacePoint*> spnts_t2_trk2;
644+ for ( size_t i = 0; i < 5; ++i ) {
645+ spnts_t2_trk2.push_back(new SciFiSpacePoint());
646+ spnts_t2_trk2[i]->set_tracker(1);
647+ spnts_t2_trk2[i]->set_station(i+1);
648+ spnts_t2_trk2[i]->set_used(false);
649+ spnts_t2_trk2[i]->set_npe(22);
650+ }
651+ std::vector<SciFiSpacePoint*> spnts_t2_trk3;
652+ for ( size_t i = 0; i < 5; ++i ) {
653+ spnts_t2_trk3.push_back(new SciFiSpacePoint());
654+ spnts_t2_trk3[i]->set_tracker(1);
655+ spnts_t2_trk3[i]->set_station(i+1);
656+ spnts_t2_trk3[i]->set_used(false);
657+ spnts_t2_trk3[i]->set_npe(23);
658+ }
659+ std::vector<SciFiSpacePoint*> spnts_t2_trk4;
660+ for ( size_t i = 0; i < 5; ++i ) {
661+ spnts_t2_trk4.push_back(new SciFiSpacePoint());
662+ spnts_t2_trk4[i]->set_tracker(1);
663+ spnts_t2_trk4[i]->set_station(i+1);
664+ spnts_t2_trk4[i]->set_used(false);
665+ spnts_t2_trk4[i]->set_npe(24);
666+ }
667+
668+ // Spill 4, mu plus
669+ spnts_t1_trk1[0]->set_position(ThreeVector(0.0, 66.44, 1100.0));
670+ spnts_t1_trk1[1]->set_position(ThreeVector(-26.4, 47.46, 750.5));
671+ spnts_t1_trk1[2]->set_position(ThreeVector(-2.491, 28.47, 450.5));
672+ spnts_t1_trk1[3]->set_position(ThreeVector(14.45, 49.18, 200.6));
673+ spnts_t1_trk1[4]->set_position(ThreeVector(1.993, 69.03, 0.6523));
674+
675+ spnts_t2_trk1[0]->set_position(ThreeVector(-26.4, 56.09, 0.6523));
676+ spnts_t2_trk1[1]->set_position(ThreeVector(-25.9, -1.726, 200.7));
677+ spnts_t2_trk1[2]->set_position(ThreeVector(43.84, -17.26, 450.7));
678+ spnts_t2_trk1[3]->set_position(ThreeVector(57.79, 63.85, 750.7));
679+ spnts_t2_trk1[4]->set_position(ThreeVector(-32.38, 47.46, 1101));
680+
681+ // Spill 5, mu plus
682+ spnts_t1_trk2[0]->set_position(ThreeVector(-16.44, 15.53, 1100.0));
683+ spnts_t1_trk2[1]->set_position(ThreeVector(-19.93, 10.35, 750.5 ));
684+ spnts_t1_trk2[2]->set_position(ThreeVector(-15.44, 9.491, 450.5));
685+ spnts_t1_trk2[3]->set_position(ThreeVector(-15.44, 12.94, 200.6));
686+ spnts_t1_trk2[4]->set_position(ThreeVector(-18.93, 13.81, 0.6523));
687+
688+ spnts_t2_trk2[0]->set_position(ThreeVector(-4.982, 15.53, 0.6523));
689+ spnts_t2_trk2[1]->set_position(ThreeVector(-12.7, -5.609, 200.7));
690+ spnts_t2_trk2[2]->set_position(ThreeVector(10.71, -20.28, 450.7));
691+ spnts_t2_trk2[3]->set_position(ThreeVector(23.41, 9.491, 750.7));
692+ spnts_t2_trk2[4]->set_position(ThreeVector(-12.95, 5.177, 1101 ));
693+
694+ // Spill 6, mu plus
695+ spnts_t1_trk3[0]->set_position(ThreeVector(-50.81, -23.3, 1100));
696+ spnts_t1_trk3[1]->set_position(ThreeVector(33.88, 8.628, 750.5));
697+ spnts_t1_trk3[2]->set_position(ThreeVector(-41.35, 44.01, 450.5));
698+ spnts_t1_trk3[3]->set_position(ThreeVector(-43.84, -31.06, 200.6));
699+ spnts_t1_trk3[4]->set_position(ThreeVector(18.93, -27.61, 0.6523 ));
700+
701+ spnts_t2_trk3[0]->set_position(ThreeVector(-3.487, 47.46, 0.6523 ));
702+ spnts_t2_trk3[1]->set_position(ThreeVector(13.95, 24.16, 200.7));
703+ spnts_t2_trk3[2]->set_position(ThreeVector(40.85, 44.87, 450.7));
704+ spnts_t2_trk3[3]->set_position(ThreeVector(8.469, 61.26, 750.7 ));
705+ spnts_t2_trk3[4]->set_position(ThreeVector(18.43, 26.75, 1101 ));
706+
707+ // Spill 2, mu minus
708+ spnts_t1_trk4[0]->set_position(ThreeVector(-0.4982, 31.06, 1100));
709+ spnts_t1_trk4[1]->set_position(ThreeVector(-9.465, -0.8628, 750.5));
710+ spnts_t1_trk4[2]->set_position(ThreeVector(20.42, 4.314, 450.5));
711+ spnts_t1_trk4[3]->set_position(ThreeVector(11.46, 30.2, 200.6));
712+ spnts_t1_trk4[4]->set_position(ThreeVector(-9.465, 25.02, 0.6523));
713+
714+ spnts_t2_trk4[0]->set_position(ThreeVector(-2.491, -19.85, 0.6523));
715+ spnts_t2_trk4[1]->set_position(ThreeVector(12.95, -24.16, 200.7));
716+ spnts_t2_trk4[2]->set_position(ThreeVector(18.93, -6.903, 450.7));
717+ spnts_t2_trk4[3]->set_position(ThreeVector(-2.491, -4.314, 750.7));
718+ spnts_t2_trk4[4]->set_position(ThreeVector(7.971, -25.89, 1101.0));
719+
720+ std::vector<SciFiSpacePoint*> spnts(spnts_t1_trk1);
721+ spnts.insert(spnts.end(), spnts_t1_trk2.begin(), spnts_t1_trk2.end());
722+ spnts.insert(spnts.end(), spnts_t1_trk3.begin(), spnts_t1_trk3.end());
723+ spnts.insert(spnts.end(), spnts_t1_trk4.begin(), spnts_t1_trk4.end());
724+ spnts.insert(spnts.end(), spnts_t2_trk1.begin(), spnts_t2_trk1.end());
725+ spnts.insert(spnts.end(), spnts_t2_trk2.begin(), spnts_t2_trk2.end());
726+ spnts.insert(spnts.end(), spnts_t2_trk3.begin(), spnts_t2_trk3.end());
727+ spnts.insert(spnts.end(), spnts_t2_trk4.begin(), spnts_t2_trk4.end());
728+
729+ return spnts;
730+ }
731 };
732
733 TEST_F(PatternRecognitionTest, test_constructor) {
734@@ -97,6 +230,8 @@
735 EXPECT_TRUE(pr._up_helical_pr_on);
736 EXPECT_TRUE(pr._down_helical_pr_on);
737 EXPECT_FALSE(pr._sp_search_on);
738+ EXPECT_EQ(0, pr._line_fitter);
739+ EXPECT_EQ(0, pr._circle_fitter);
740 EXPECT_EQ(0, pr._verb);
741 EXPECT_EQ(2, pr._n_trackers);
742 EXPECT_EQ(5, pr._n_stations);
743@@ -124,6 +259,8 @@
744 EXPECT_TRUE(pr._up_helical_pr_on);
745 EXPECT_TRUE(pr._down_helical_pr_on);
746 EXPECT_FALSE(pr._sp_search_on);
747+ EXPECT_EQ(0, pr._line_fitter);
748+ EXPECT_EQ(0, pr._circle_fitter);
749 EXPECT_EQ(0, pr._verb);
750 EXPECT_EQ(2, pr._n_trackers);
751 EXPECT_EQ(5, pr._n_stations);
752@@ -149,7 +286,7 @@
753 pr.set_parameters_to_default();
754
755 // Set up the spacepoints vector
756- std::vector<SciFiSpacePoint*> spnts = set_up_spacepoints();
757+ std::vector<SciFiSpacePoint*> spnts = set_up_single_track_spacepoints();
758
759 // For a straight fit
760 // ------------------
761@@ -216,131 +353,14 @@
762 }
763 */
764
765-TEST_F(PatternRecognitionTest, test_multiple_evts_per_trigger) {
766+TEST_F(PatternRecognitionTest, test_multiple_evts_per_trigger_lsq) {
767
768 PatternRecognition pr;
769 pr.set_parameters_to_default();
770+ pr.set_circle_fitter(0);
771
772 // Set up the spacepoints vector
773- std::vector<SciFiSpacePoint*> spnts_t1_trk1;
774- for ( size_t i = 0; i < 5; ++i ) {
775- spnts_t1_trk1.push_back(new SciFiSpacePoint());
776- spnts_t1_trk1[i]->set_tracker(0);
777- spnts_t1_trk1[i]->set_station(5-i);
778- spnts_t1_trk1[i]->set_used(false);
779- }
780- std::vector<SciFiSpacePoint*> spnts_t1_trk2;
781- for ( size_t i = 0; i < 5; ++i ) {
782- spnts_t1_trk2.push_back(new SciFiSpacePoint());
783- spnts_t1_trk2[i]->set_tracker(0);
784- spnts_t1_trk2[i]->set_station(5-i);
785- spnts_t1_trk2[i]->set_used(false);
786- }
787- std::vector<SciFiSpacePoint*> spnts_t1_trk3;
788- for ( size_t i = 0; i < 5; ++i ) {
789- spnts_t1_trk3.push_back(new SciFiSpacePoint());
790- spnts_t1_trk3[i]->set_tracker(0);
791- spnts_t1_trk3[i]->set_station(5-i);
792- spnts_t1_trk3[i]->set_used(false);
793- }
794- std::vector<SciFiSpacePoint*> spnts_t1_trk4;
795- for ( size_t i = 0; i < 5; ++i ) {
796- spnts_t1_trk4.push_back(new SciFiSpacePoint());
797- spnts_t1_trk4[i]->set_tracker(0);
798- spnts_t1_trk4[i]->set_station(5-i);
799- spnts_t1_trk4[i]->set_used(false);
800- }
801-
802- std::vector<SciFiSpacePoint*> spnts_t2_trk1;
803- for ( size_t i = 0; i < 5; ++i ) {
804- spnts_t2_trk1.push_back(new SciFiSpacePoint());
805- spnts_t2_trk1[i]->set_tracker(1);
806- spnts_t2_trk1[i]->set_station(i+1);
807- spnts_t2_trk1[i]->set_used(false);
808- }
809- std::vector<SciFiSpacePoint*> spnts_t2_trk2;
810- for ( size_t i = 0; i < 5; ++i ) {
811- spnts_t2_trk2.push_back(new SciFiSpacePoint());
812- spnts_t2_trk2[i]->set_tracker(1);
813- spnts_t2_trk2[i]->set_station(i+1);
814- spnts_t2_trk2[i]->set_used(false);
815- }
816- std::vector<SciFiSpacePoint*> spnts_t2_trk3;
817- for ( size_t i = 0; i < 5; ++i ) {
818- spnts_t2_trk3.push_back(new SciFiSpacePoint());
819- spnts_t2_trk3[i]->set_tracker(1);
820- spnts_t2_trk3[i]->set_station(i+1);
821- spnts_t2_trk3[i]->set_used(false);
822- }
823- std::vector<SciFiSpacePoint*> spnts_t2_trk4;
824- for ( size_t i = 0; i < 5; ++i ) {
825- spnts_t2_trk4.push_back(new SciFiSpacePoint());
826- spnts_t2_trk4[i]->set_tracker(1);
827- spnts_t2_trk4[i]->set_station(i+1);
828- spnts_t2_trk4[i]->set_used(false);
829- }
830-
831-
832- // Spill 4, mu plus
833- spnts_t1_trk1[0]->set_position(ThreeVector(0.0, 66.44, 1100.0));
834- spnts_t1_trk1[1]->set_position(ThreeVector(-26.4, 47.46, 750.5));
835- spnts_t1_trk1[2]->set_position(ThreeVector(-2.491, 28.47, 450.5));
836- spnts_t1_trk1[3]->set_position(ThreeVector(14.45, 49.18, 200.6));
837- spnts_t1_trk1[4]->set_position(ThreeVector(1.993, 69.03, 0.6523));
838-
839- spnts_t2_trk1[0]->set_position(ThreeVector(-26.4, 56.09, 0.6523));
840- spnts_t2_trk1[1]->set_position(ThreeVector(-25.9, -1.726, 200.7));
841- spnts_t2_trk1[2]->set_position(ThreeVector(43.84, -17.26, 450.7));
842- spnts_t2_trk1[3]->set_position(ThreeVector(57.79, 63.85, 750.7));
843- spnts_t2_trk1[4]->set_position(ThreeVector(-32.38, 47.46, 1101));
844-
845- // Spill 5, mu plus
846- spnts_t1_trk2[0]->set_position(ThreeVector(-16.44, 15.53, 1100.0));
847- spnts_t1_trk2[1]->set_position(ThreeVector(-19.93, 10.35, 750.5 ));
848- spnts_t1_trk2[2]->set_position(ThreeVector(-15.44, 9.491, 450.5));
849- spnts_t1_trk2[3]->set_position(ThreeVector(-15.44, 12.94, 200.6));
850- spnts_t1_trk2[4]->set_position(ThreeVector(-18.93, 13.81, 0.6523));
851-
852- spnts_t2_trk2[0]->set_position(ThreeVector(-4.982, 15.53, 0.6523));
853- spnts_t2_trk2[1]->set_position(ThreeVector(-12.7, -5.609, 200.7));
854- spnts_t2_trk2[2]->set_position(ThreeVector(10.71, -20.28, 450.7));
855- spnts_t2_trk2[3]->set_position(ThreeVector(23.41, 9.491, 750.7));
856- spnts_t2_trk2[4]->set_position(ThreeVector(-12.95, 5.177, 1101 ));
857-
858- // Spill 6, mu plus
859- spnts_t1_trk3[0]->set_position(ThreeVector(-50.81, -23.3, 1100));
860- spnts_t1_trk3[1]->set_position(ThreeVector(33.88, 8.628, 750.5));
861- spnts_t1_trk3[2]->set_position(ThreeVector(-41.35, 44.01, 450.5));
862- spnts_t1_trk3[3]->set_position(ThreeVector(-43.84, -31.06, 200.6));
863- spnts_t1_trk3[4]->set_position(ThreeVector(18.93, -27.61, 0.6523 ));
864-
865- spnts_t2_trk3[0]->set_position(ThreeVector(-3.487, 47.46, 0.6523 ));
866- spnts_t2_trk3[1]->set_position(ThreeVector(13.95, 24.16, 200.7));
867- spnts_t2_trk3[2]->set_position(ThreeVector(40.85, 44.87, 450.7));
868- spnts_t2_trk3[3]->set_position(ThreeVector(8.469, 61.26, 750.7 ));
869- spnts_t2_trk3[4]->set_position(ThreeVector(18.43, 26.75, 1101 ));
870-
871- // Spill 2, mu minus
872- spnts_t1_trk4[0]->set_position(ThreeVector(-0.4982, 31.06, 1100));
873- spnts_t1_trk4[1]->set_position(ThreeVector(-9.465, -0.8628, 750.5));
874- spnts_t1_trk4[2]->set_position(ThreeVector(20.42, 4.314, 450.5));
875- spnts_t1_trk4[3]->set_position(ThreeVector(11.46, 30.2, 200.6));
876- spnts_t1_trk4[4]->set_position(ThreeVector(-9.465, 25.02, 0.6523));
877-
878- spnts_t2_trk4[0]->set_position(ThreeVector(-2.491, -19.85, 0.6523));
879- spnts_t2_trk4[1]->set_position(ThreeVector(12.95, -24.16, 200.7));
880- spnts_t2_trk4[2]->set_position(ThreeVector(18.93, -6.903, 450.7));
881- spnts_t2_trk4[3]->set_position(ThreeVector(-2.491, -4.314, 750.7));
882- spnts_t2_trk4[4]->set_position(ThreeVector(7.971, -25.89, 1101.0));
883-
884- std::vector<SciFiSpacePoint*> spnts(spnts_t1_trk1);
885- spnts.insert(spnts.end(), spnts_t1_trk2.begin(), spnts_t1_trk2.end());
886- spnts.insert(spnts.end(), spnts_t1_trk3.begin(), spnts_t1_trk3.end());
887- spnts.insert(spnts.end(), spnts_t1_trk4.begin(), spnts_t1_trk4.end());
888- spnts.insert(spnts.end(), spnts_t2_trk1.begin(), spnts_t2_trk1.end());
889- spnts.insert(spnts.end(), spnts_t2_trk2.begin(), spnts_t2_trk2.end());
890- spnts.insert(spnts.end(), spnts_t2_trk3.begin(), spnts_t2_trk3.end());
891- spnts.insert(spnts.end(), spnts_t2_trk4.begin(), spnts_t2_trk4.end());
892+ std::vector<SciFiSpacePoint*> spnts = set_up_multiple_track_spacepoints();
893 SciFiEvent evt1;
894 evt1.set_spacepoints(spnts);
895
896@@ -377,6 +397,14 @@
897 EXPECT_EQ(5, htrks[5]->get_num_points());
898 EXPECT_EQ(5, htrks[6]->get_num_points());
899 EXPECT_EQ(5, htrks[7]->get_num_points());
900+ // Check npe, which we used to encode which sp belongs to which tracks
901+ for (SciFiHelicalPRTrack* trk : htrks) {
902+ std::vector<SciFiSpacePoint*> spnts = trk->get_spacepoints_pointers();
903+ EXPECT_NEAR(spnts[1]->get_npe(), spnts[0]->get_npe(), 0.01);
904+ EXPECT_NEAR(spnts[2]->get_npe(), spnts[0]->get_npe(), 0.01);
905+ EXPECT_NEAR(spnts[3]->get_npe(), spnts[0]->get_npe(), 0.01);
906+ EXPECT_NEAR(spnts[4]->get_npe(), spnts[0]->get_npe(), 0.01);
907+ }
908 EXPECT_NEAR(htrks[0]->get_dsdz(), -0.1156, 0.001);
909 EXPECT_NEAR(htrks[1]->get_dsdz(), -0.342, 0.01);
910 EXPECT_NEAR(htrks[2]->get_dsdz(), -0.01834, 0.01);
911@@ -385,14 +413,74 @@
912 EXPECT_NEAR(htrks[5]->get_dsdz(), 0.3126, 0.001);
913 EXPECT_NEAR(htrks[6]->get_dsdz(), 0.08396, 0.001);
914 EXPECT_NEAR(htrks[7]->get_dsdz(), 0.1257, 0.001);
915-
916- // evt descoping will delete the spacepoints
917+}
918+
919+TEST_F(PatternRecognitionTest, test_multiple_evts_per_trigger_rootfit) {
920+
921+ PatternRecognition pr;
922+ pr.set_parameters_to_default();
923+ pr.set_circle_fitter(1);
924+
925+ // Set up the spacepoints vector
926+ std::vector<SciFiSpacePoint*> spnts = set_up_multiple_track_spacepoints();
927+ SciFiEvent evt1;
928+ evt1.set_spacepoints(spnts);
929+
930+ // Randomise things a bit to make it harder
931+ SciFiSpacePoint *sp1, *sp2;
932+ sp1 = spnts[3];
933+ sp2 = spnts[14];
934+ spnts[3] = sp2;
935+ spnts[14] = sp1;
936+ sp1 = spnts[4];
937+ sp2 = spnts[17];
938+ spnts[4] = sp2;
939+ spnts[17] = sp1;
940+
941+ // Perform the recon
942+ pr.set_up_helical_pr_on(true);
943+ pr.set_down_helical_pr_on(true);
944+ pr.set_up_straight_pr_on(false);
945+ pr.set_down_straight_pr_on(false);
946+ pr.process(evt1);
947+
948+ std::vector<SciFiStraightPRTrack*> strks;
949+ std::vector<SciFiHelicalPRTrack*> htrks;
950+ strks = evt1.straightprtracks();
951+ htrks = evt1.helicalprtracks();
952+
953+ ASSERT_EQ(8u, htrks.size());
954+ EXPECT_EQ(0u, strks.size());
955+ EXPECT_EQ(5, htrks[0]->get_num_points());
956+ EXPECT_EQ(5, htrks[1]->get_num_points());
957+ EXPECT_EQ(5, htrks[2]->get_num_points());
958+ EXPECT_EQ(5, htrks[3]->get_num_points());
959+ EXPECT_EQ(5, htrks[4]->get_num_points());
960+ EXPECT_EQ(5, htrks[5]->get_num_points());
961+ EXPECT_EQ(5, htrks[6]->get_num_points());
962+ EXPECT_EQ(5, htrks[7]->get_num_points());
963+ // Check npe, which we used to encode which sp belongs to which tracks
964+ for (SciFiHelicalPRTrack* trk : htrks) {
965+ std::vector<SciFiSpacePoint*> spnts = trk->get_spacepoints_pointers();
966+ EXPECT_NEAR(spnts[1]->get_npe(), spnts[0]->get_npe(), 0.01);
967+ EXPECT_NEAR(spnts[2]->get_npe(), spnts[0]->get_npe(), 0.01);
968+ EXPECT_NEAR(spnts[3]->get_npe(), spnts[0]->get_npe(), 0.01);
969+ EXPECT_NEAR(spnts[4]->get_npe(), spnts[0]->get_npe(), 0.01);
970+ }
971+ EXPECT_NEAR(htrks[0]->get_dsdz(), -0.342, 0.01);
972+ EXPECT_NEAR(htrks[1]->get_dsdz(), -0.1156, 0.005);
973+ EXPECT_NEAR(htrks[2]->get_dsdz(), -0.01834, 0.01);
974+ EXPECT_NEAR(htrks[3]->get_dsdz(), -0.1178, 0.01);
975+ EXPECT_NEAR(htrks[4]->get_dsdz(), 0.08396, 0.001);
976+ EXPECT_NEAR(htrks[5]->get_dsdz(), 0.3126, 0.001);
977+ EXPECT_NEAR(htrks[6]->get_dsdz(), 0.1257, 0.001);
978+ EXPECT_NEAR(htrks[7]->get_dsdz(), 0.1504, 0.001);
979 }
980
981 TEST_F(PatternRecognitionTest, test_make_tracks) {
982
983 // Set up the spacepoints vector
984- std::vector<SciFiSpacePoint*> spnts_all = set_up_spacepoints();
985+ std::vector<SciFiSpacePoint*> spnts_all = set_up_single_track_spacepoints();
986 std::vector<SciFiSpacePoint*> spnts;
987 spnts.push_back(spnts_all[4]);
988 spnts.push_back(spnts_all[1]);
989@@ -517,7 +605,7 @@
990 TEST_F(PatternRecognitionTest, test_make_4pt_tracks) {
991
992 // Set up the spacepoints vector
993- std::vector<SciFiSpacePoint*> spnts_all = set_up_spacepoints();
994+ std::vector<SciFiSpacePoint*> spnts_all = set_up_single_track_spacepoints();
995 std::vector<SciFiSpacePoint*> spnts;
996 spnts.push_back(spnts_all[4]);
997 spnts.push_back(spnts_all[2]);
998@@ -617,7 +705,7 @@
999 TEST_F(PatternRecognitionTest, test_make_3pt_tracks) {
1000
1001 // Set up the spacepoints vector
1002- std::vector<SciFiSpacePoint*> spnts_all = set_up_spacepoints();
1003+ std::vector<SciFiSpacePoint*> spnts_all = set_up_single_track_spacepoints();
1004 std::vector<SciFiSpacePoint*> spnts;
1005 spnts.push_back(spnts_all[4]);
1006 spnts.push_back(spnts_all[1]);
1007@@ -737,15 +825,75 @@
1008 }
1009 }
1010
1011-TEST_F(PatternRecognitionTest, test_make_straight_tracks) {
1012-
1013- int n_stations = 5;
1014- int tracker_num = 0;
1015- PatternRecognition pr;
1016- pr.set_parameters_to_default();
1017-
1018- // Set up the spacepoints vector
1019- std::vector<SciFiSpacePoint*> spnts = set_up_spacepoints();
1020+TEST_F(PatternRecognitionTest, test_make_straight_tracks_lsq) {
1021+
1022+ int n_stations = 5;
1023+ int tracker_num = 0;
1024+ PatternRecognition pr;
1025+ pr.set_parameters_to_default();
1026+ pr.set_line_fitter(0);
1027+
1028+ // Set up the spacepoints vector
1029+ std::vector<SciFiSpacePoint*> spnts = set_up_single_track_spacepoints();
1030+
1031+ // Set up the spacepoints by station 2D vector
1032+ std::vector< std::vector<SciFiSpacePoint*> > spnts_by_station(n_stations);
1033+ SciFiTools::sort_by_station(spnts, spnts_by_station);
1034+
1035+ // Check the spacepoints have setup correctly
1036+ EXPECT_EQ(spnts[0], spnts_by_station[0][0]);
1037+ EXPECT_EQ(spnts[1], spnts_by_station[1][0]);
1038+ EXPECT_EQ(spnts[2], spnts_by_station[2][0]);
1039+ EXPECT_EQ(spnts[3], spnts_by_station[3][0]);
1040+ EXPECT_EQ(spnts[4], spnts_by_station[4][0]);
1041+ EXPECT_EQ(-68.24883333333334, spnts_by_station[0][0]->get_position().x());
1042+
1043+ std::vector<int> ignore_stations;
1044+ std::vector<SciFiStraightPRTrack*> strks;
1045+
1046+ // The track parameters that should be reconstructed from the spacepoints
1047+ int num_points = 5;
1048+ double x_chisq = 22.87148204;
1049+ double y_chisq = 20.99052559;
1050+ double y0 = -58.85201389;
1051+ double x0 = -68.94108927;
1052+ double my = 0.03755825;
1053+ double mx = -0.02902014;
1054+
1055+ // Make the track from the spacepoints
1056+ pr.make_straight_tracks(num_points, tracker_num, ignore_stations, spnts_by_station, strks);
1057+
1058+ // Check it matches to within a tolerance epsilon
1059+ double epsilon = 0.000001;
1060+ EXPECT_EQ(1u, strks.size());
1061+ EXPECT_NEAR(x0, strks[0]->get_x0(), epsilon);
1062+ EXPECT_NEAR(mx, strks[0]->get_mx(), epsilon);
1063+ EXPECT_NEAR(x_chisq, strks[0]->get_x_chisq(), epsilon);
1064+ EXPECT_NEAR(y0, strks[0]->get_y0(), epsilon);
1065+ EXPECT_NEAR(my, strks[0]->get_my(), epsilon);
1066+ EXPECT_NEAR(y_chisq, strks[0]->get_y_chisq(), epsilon);
1067+
1068+ // Tidy up
1069+ std::vector<SciFiSpacePoint*>::iterator it;
1070+ for (it = spnts.begin(); it != spnts.end(); ++it) {
1071+ delete (*it);
1072+ }
1073+ std::vector<SciFiStraightPRTrack*>::iterator strack;
1074+ for (strack = strks.begin(); strack != strks.end(); ++strack) {
1075+ delete (*strack);
1076+ }
1077+}
1078+
1079+TEST_F(PatternRecognitionTest, test_make_straight_tracks_rootfit) {
1080+
1081+ int n_stations = 5;
1082+ int tracker_num = 0;
1083+ PatternRecognition pr;
1084+ pr.set_parameters_to_default();
1085+ pr.set_line_fitter(1);
1086+
1087+ // Set up the spacepoints vector
1088+ std::vector<SciFiSpacePoint*> spnts = set_up_single_track_spacepoints();
1089
1090 // Set up the spacepoints by station 2D vector
1091 std::vector< std::vector<SciFiSpacePoint*> > spnts_by_station(n_stations);
1092
1093=== modified file 'tests/cpp_unit/Recon/SciFi/SimpleCircleTest.cc'
1094--- tests/cpp_unit/Recon/SciFi/SimpleCircleTest.cc 2013-07-09 17:12:03 +0000
1095+++ tests/cpp_unit/Recon/SciFi/SimpleCircleTest.cc 2017-06-08 17:10:31 +0000
1096@@ -92,9 +92,10 @@
1097 double kappa_err = 0.8;
1098 double delta_R = 9;
1099 double chisq = 10;
1100+ double pvalue = 11.0;
1101
1102 SimpleCircle circ1(x0, x0_err, y0, y0_err, R, R_err, alpha, alpha_err, beta, beta_err,
1103- gamma, gamma_err, kappa, kappa_err, delta_R, chisq);
1104+ gamma, gamma_err, kappa, kappa_err, delta_R, chisq, pvalue);
1105
1106 EXPECT_EQ(circ1.get_x0(), x0);
1107 EXPECT_EQ(circ1.get_x0_err(), x0_err);
1108@@ -112,6 +113,7 @@
1109 EXPECT_EQ(circ1.get_kappa_err(), kappa_err);
1110 EXPECT_EQ(circ1.get_delta_R(), delta_R);
1111 EXPECT_EQ(circ1.get_chisq(), chisq);
1112+ EXPECT_EQ(circ1.get_pvalue(), pvalue);
1113 }
1114
1115 TEST_F(SimpleCircleTestDS, test_getters_setters_clear) {
1116@@ -131,6 +133,7 @@
1117 double kappa_err = 0.8;
1118 double delta_R = 9.0;
1119 double chisq = 10.0;
1120+ double pvalue = 11.0;
1121
1122 SimpleCircle circ1;
1123
1124@@ -150,6 +153,7 @@
1125 circ1.set_kappa_err(kappa_err);
1126 circ1.set_delta_R(delta_R);
1127 circ1.set_chisq(chisq);
1128+ circ1.set_pvalue(pvalue);
1129
1130 EXPECT_EQ(circ1.get_x0(), x0);
1131 EXPECT_EQ(circ1.get_x0_err(), x0_err);
1132@@ -167,6 +171,7 @@
1133 EXPECT_EQ(circ1.get_kappa_err(), kappa_err);
1134 EXPECT_EQ(circ1.get_delta_R(), delta_R);
1135 EXPECT_EQ(circ1.get_chisq(), chisq);
1136+ EXPECT_EQ(circ1.get_pvalue(), pvalue);
1137
1138 circ1.clear();
1139
1140@@ -186,9 +191,10 @@
1141 EXPECT_EQ(circ1.get_kappa_err(), 0.0);
1142 EXPECT_EQ(circ1.get_delta_R(), 0.0);
1143 EXPECT_EQ(circ1.get_chisq(), 0.0);
1144+ EXPECT_EQ(circ1.get_pvalue(), 0.0);
1145
1146 circ1.set_parameters(x0, x0_err, y0, y0_err, R, R_err, alpha, alpha_err, beta, beta_err,
1147- gamma, gamma_err, kappa, kappa_err, delta_R, chisq);
1148+ gamma, gamma_err, kappa, kappa_err, delta_R, chisq, pvalue);
1149
1150 EXPECT_EQ(circ1.get_x0(), x0);
1151 EXPECT_EQ(circ1.get_x0_err(), x0_err);
1152@@ -206,6 +212,7 @@
1153 EXPECT_EQ(circ1.get_kappa_err(), kappa_err);
1154 EXPECT_EQ(circ1.get_delta_R(), delta_R);
1155 EXPECT_EQ(circ1.get_chisq(), chisq);
1156+ EXPECT_EQ(circ1.get_pvalue(), pvalue);
1157 }
1158
1159 } // ~namespace MAUS
1160
1161=== modified file 'tests/py_unit/test_maus_cpp/test_optics/test_optics_model.py'
1162--- tests/py_unit/test_maus_cpp/test_optics/test_optics_model.py 2015-07-08 10:26:19 +0000
1163+++ tests/py_unit/test_maus_cpp/test_optics/test_optics_model.py 2017-06-08 17:10:31 +0000
1164@@ -1,3 +1,5 @@
1165+#!/usr/bin/env python
1166+
1167 # This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
1168 #
1169 # MAUS is free software: you can redistribute it and/or modify
1170@@ -19,20 +21,171 @@
1171 Test maus_cpp.optics_model
1172 """
1173
1174+import json
1175+import unittest
1176 import os
1177-import subprocess
1178-import unittest
1179+
1180+import Configuration
1181+import maus_cpp.globals
1182+import maus_cpp.mice_module
1183+import maus_cpp.covariance_matrix
1184+from maus_cpp.covariance_matrix import CovarianceMatrix
1185+import maus_cpp.phase_space_vector
1186+from maus_cpp.phase_space_vector import PhaseSpaceVector
1187+import maus_cpp.optics_model
1188+from maus_cpp.optics_model import OpticsModel
1189+
1190+REF = {
1191+ "position":{"x":0., "y":0., "z":1000.001},
1192+ "momentum":{"x":0., "y":0., "z":1.},
1193+ "particle_id":-13, "energy":226., "random_seed":0, "time":0.
1194+}
1195
1196 class OpticsModelTestCase(unittest.TestCase): # pylint: disable=R0904
1197 """Test maus_cpp.optics_model"""
1198- def test_optics_model(self): #pylint: disable=R0201
1199- """
1200- Test optics model runs in a subprocess to prevent pollution of globals
1201- """
1202- test = os.path.expandvars(\
1203+ def setUp(self):
1204+ """import datacards"""
1205+ self.test_config = ""
1206+ self.good_mod = os.path.expandvars(\
1207 "${MAUS_ROOT_DIR}/tests/py_unit/test_maus_cpp/"+\
1208- "test_optics/test_optics_model_subprocess")
1209- subprocess.check_call(test)
1210+ "test_optics/optics_model.dat")
1211+ self.no_planes_mod = os.path.expandvars("Test.dat")
1212+
1213+ def _set_geometry(self, geom_filename):
1214+ """Geometry setup"""
1215+ if maus_cpp.globals.has_instance():
1216+ maus_cpp.globals.death()
1217+ self.test_config = Configuration.Configuration().getConfigJSON()
1218+ json_config = json.loads(self.test_config)
1219+ json_config["simulation_geometry_filename"] = geom_filename
1220+ json_config["simulation_reference_particle"] = REF
1221+ json_config["physics_processes"] = "none"
1222+ self.test_config = json.dumps(json_config)
1223+ maus_cpp.globals.birth(self.test_config)
1224+ maus_cpp.globals.set_monte_carlo_mice_modules(
1225+ maus_cpp.mice_module.MiceModule(geom_filename))
1226+
1227+ def test_init_no_globals(self):
1228+ """Test maus_cpp.optics_model.__init__() and deallocation"""
1229+ if maus_cpp.globals.has_instance():
1230+ maus_cpp.globals.death()
1231+ try:
1232+ OpticsModel()
1233+ self.assertTrue(False, msg="Should throw an exception if globals "+\
1234+ "is not initialised")
1235+ except RuntimeError:
1236+ pass
1237+
1238+ def test_init_all_okay(self):
1239+ """Test maus_cpp.optics_model.__init__() and deallocation"""
1240+ self._set_geometry(self.good_mod)
1241+ optics = OpticsModel()
1242+ optics.__init__() # legal, should reinitialise
1243+
1244+ def test_transport_covariance_matrix_no_planes(self):
1245+ """
1246+ Test maus_cpp.optics_model.Optics().transport_covariance_matrix()
1247+ with no virtuals
1248+ """
1249+ self._set_geometry(self.no_planes_mod)
1250+ optics = OpticsModel()
1251+ cm_in = CovarianceMatrix()
1252+ try:
1253+ optics.transport_covariance_matrix(cm_in, 2000.)
1254+ self.assertTrue(False, "Should throw when no virtuals")
1255+ except RuntimeError:
1256+ pass
1257+
1258+ def test_transport_covariance_matrix_bad_type(self):
1259+ """
1260+ Test maus_cpp.optics_model.Optics().transport_covariance_matrix()
1261+ with non cm
1262+ """
1263+ self._set_geometry(self.good_mod)
1264+ optics = OpticsModel()
1265+ try:
1266+ optics.transport_covariance_matrix("should be a cm", 2000.)
1267+ self.assertTrue(False, "Should throw when wrong type passed")
1268+ except TypeError:
1269+ pass
1270+
1271+ def test_transport_covariance_matrix(self):
1272+ """Test maus_cpp.optics_model.Optics().transport_covariance_matrix()"""
1273+ self._set_geometry(self.good_mod)
1274+ optics = OpticsModel()
1275+ cm_in = maus_cpp.covariance_matrix.create_from_penn_parameters(
1276+ mass=105.658, momentum=200., emittance_t=6., beta_t=333.,
1277+ emittance_l=1., beta_l=10., bz=0.)
1278+ # check energy, px RMS does not change (no fields)
1279+ cm_out_1 = optics.transport_covariance_matrix(cm_in, 2000.)
1280+ for i in [2, 4, 6]:
1281+ self.assertAlmostEqual(cm_in.get_element(i, i),
1282+ cm_out_1.get_element(i, i), 1,
1283+ msg="\nIN\n"+str(cm_in)+"\nOUT\n"+str(cm_out_1))
1284+ cm_out_2 = optics.transport_covariance_matrix(cm_in, 3000.)
1285+ for i in range(3):
1286+ self.assertGreater(abs(cm_out_1.get_element(2*i+1, 2*i+2)), 1.)
1287+ # check that we have some growth of correlation between e.g. x, px
1288+ self.assertAlmostEqual(cm_out_1.get_element(3, 4),
1289+ cm_out_1.get_element(5, 6), 2)
1290+ for i in [2, 4, 6]:
1291+ self.assertAlmostEqual(cm_in.get_element(i, i),
1292+ cm_out_2.get_element(i, i), 1,
1293+ msg="\nIN\n"+str(cm_in)+"\nOUT\n"+str(cm_out_2))
1294+ # check no coupling between phase space planes
1295+ for i in [2, 4, 5]:
1296+ self.assertAlmostEqual(
1297+ cm_in.get_element(i+1, i)-cm_out_1.get_element(i+1, i),
1298+ cm_out_1.get_element(i+1, i)-cm_out_2.get_element(i+1, i),
1299+ 1,
1300+ msg="\nIN\n"+str(cm_in)+"\nOUT\n"+str(cm_out_2))
1301+
1302+
1303+ def test_transport_phase_space_vector_no_planes(self):
1304+ """
1305+ Test maus_cpp.optics_model.Optics().transport_phase_space_vector() with
1306+ no virtuals
1307+ """
1308+ self._set_geometry(self.no_planes_mod)
1309+ optics = OpticsModel()
1310+ psv_in = PhaseSpaceVector()
1311+ try:
1312+ optics.transport_phase_space_vector(psv_in, 2000.)
1313+ self.assertTrue(False, "Should throw when no virtuals")
1314+ except RuntimeError:
1315+ pass
1316+
1317+ def test_transport_phase_space_vector_bad_type(self):
1318+ """
1319+ Test maus_cpp.optics_model.Optics().transport_phase_space_vector() with
1320+ no virtuals
1321+ """
1322+ self._set_geometry(self.good_mod)
1323+ optics = OpticsModel()
1324+ try:
1325+ optics.transport_phase_space_vector("should be a psv", 2000.)
1326+ self.assertTrue(False, "Should throw when wrong type passed")
1327+ except TypeError:
1328+ pass
1329+
1330+ def test_transport_phase_space_vector(self):
1331+ """Test maus_cpp.optics_model.Optics().transport_phase_space_vector()"""
1332+ self._set_geometry(self.good_mod)
1333+ optics = OpticsModel()
1334+ psv_in = maus_cpp.phase_space_vector.create_from_coordinates \
1335+ (0.1, 226., 1., 2., 3., 4.)
1336+ psv_out = optics.transport_phase_space_vector(psv_in, 2000.)
1337+ pz = (226.**2-105.6583715**2.-2.**2-4.**2)**0.5
1338+ dz = 1000.
1339+ t_expected = psv_in.get_t()+psv_out.get_energy()/pz/300.*dz # c=300.
1340+ x_expected = psv_in.get_x()+psv_in.get_px()/pz*dz
1341+ y_expected = psv_in.get_y()+psv_in.get_py()/pz*dz
1342+ self.assertAlmostEqual(psv_out.get_t()/t_expected, 1, 3)
1343+ self.assertAlmostEqual(psv_out.get_energy()/psv_in.get_energy(), 1., 5)
1344+ self.assertAlmostEqual(psv_out.get_x()/x_expected, 1., 3)
1345+ self.assertAlmostEqual(psv_out.get_px()/psv_in.get_px(), 1., 5)
1346+ self.assertAlmostEqual(psv_out.get_y()/y_expected, 1., 3)
1347+ self.assertAlmostEqual(psv_out.get_py()/psv_in.get_py(), 1., 5)
1348
1349 if __name__ == "__main__":
1350 unittest.main()
1351
1352=== removed file 'tests/py_unit/test_maus_cpp/test_optics/test_optics_model_subprocess'
1353--- tests/py_unit/test_maus_cpp/test_optics/test_optics_model_subprocess 2015-07-08 10:06:34 +0000
1354+++ tests/py_unit/test_maus_cpp/test_optics/test_optics_model_subprocess 1970-01-01 00:00:00 +0000
1355@@ -1,192 +0,0 @@
1356-#!/usr/bin/env python
1357-
1358-# This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
1359-#
1360-# MAUS is free software: you can redistribute it and/or modify
1361-# it under the terms of the GNU General Public License as published by
1362-# the Free Software Foundation, either version 3 of the License, or
1363-# (at your option) any later version.
1364-#
1365-# MAUS is distributed in the hope that it will be useful,
1366-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1367-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1368-# GNU General Public License for more details.
1369-#
1370-# You should have received a copy of the GNU General Public License
1371-# along with MAUS. If not, see <http://www.gnu.org/licenses/>.
1372-
1373-# pylint: disable=C0103
1374-
1375-"""
1376-Test maus_cpp.optics_model
1377-"""
1378-
1379-import json
1380-import unittest
1381-import os
1382-
1383-import Configuration
1384-import maus_cpp.globals
1385-import maus_cpp.mice_module
1386-import maus_cpp.covariance_matrix
1387-from maus_cpp.covariance_matrix import CovarianceMatrix
1388-import maus_cpp.phase_space_vector
1389-from maus_cpp.phase_space_vector import PhaseSpaceVector
1390-import maus_cpp.optics_model
1391-from maus_cpp.optics_model import OpticsModel
1392-
1393-REF = {
1394- "position":{"x":0., "y":0., "z":1000.001},
1395- "momentum":{"x":0., "y":0., "z":1.},
1396- "particle_id":-13, "energy":226., "random_seed":0, "time":0.
1397-}
1398-
1399-class OpticsModelTestCase(unittest.TestCase): # pylint: disable=R0904
1400- """Test maus_cpp.optics_model"""
1401- def setUp(self):
1402- """import datacards"""
1403- self.test_config = ""
1404- self.good_mod = os.path.expandvars(\
1405- "${MAUS_ROOT_DIR}/tests/py_unit/test_maus_cpp/"+\
1406- "test_optics/optics_model.dat")
1407- self.no_planes_mod = os.path.expandvars("Test.dat")
1408-
1409- def _set_geometry(self, geom_filename):
1410- """Geometry setup"""
1411- if maus_cpp.globals.has_instance():
1412- maus_cpp.globals.death()
1413- self.test_config = Configuration.Configuration().getConfigJSON()
1414- json_config = json.loads(self.test_config)
1415- json_config["simulation_geometry_filename"] = geom_filename
1416- json_config["simulation_reference_particle"] = REF
1417- json_config["physics_processes"] = "none"
1418- self.test_config = json.dumps(json_config)
1419- maus_cpp.globals.birth(self.test_config)
1420- maus_cpp.globals.set_monte_carlo_mice_modules(
1421- maus_cpp.mice_module.MiceModule(geom_filename))
1422-
1423- def test_init_no_globals(self):
1424- """Test maus_cpp.optics_model.__init__() and deallocation"""
1425- if maus_cpp.globals.has_instance():
1426- maus_cpp.globals.death()
1427- try:
1428- OpticsModel()
1429- self.assertTrue(False, msg="Should throw an exception if globals "+\
1430- "is not initialised")
1431- except RuntimeError:
1432- pass
1433-
1434- def test_init_all_okay(self):
1435- """Test maus_cpp.optics_model.__init__() and deallocation"""
1436- self._set_geometry(self.good_mod)
1437- optics = OpticsModel()
1438- optics.__init__() # legal, should reinitialise
1439-
1440- def test_transport_covariance_matrix_no_planes(self):
1441- """
1442- Test maus_cpp.optics_model.Optics().transport_covariance_matrix()
1443- with no virtuals
1444- """
1445- self._set_geometry(self.no_planes_mod)
1446- optics = OpticsModel()
1447- cm_in = CovarianceMatrix()
1448- try:
1449- optics.transport_covariance_matrix(cm_in, 2000.)
1450- self.assertTrue(False, "Should throw when no virtuals")
1451- except RuntimeError:
1452- pass
1453-
1454- def test_transport_covariance_matrix_bad_type(self):
1455- """
1456- Test maus_cpp.optics_model.Optics().transport_covariance_matrix()
1457- with non cm
1458- """
1459- self._set_geometry(self.good_mod)
1460- optics = OpticsModel()
1461- try:
1462- optics.transport_covariance_matrix("should be a cm", 2000.)
1463- self.assertTrue(False, "Should throw when wrong type passed")
1464- except TypeError:
1465- pass
1466-
1467- def test_transport_covariance_matrix(self):
1468- """Test maus_cpp.optics_model.Optics().transport_covariance_matrix()"""
1469- self._set_geometry(self.good_mod)
1470- optics = OpticsModel()
1471- cm_in = maus_cpp.covariance_matrix.create_from_penn_parameters(
1472- mass=105.658, momentum=200., emittance_t=6., beta_t=333.,
1473- emittance_l=1., beta_l=10., bz=0.)
1474- # check energy, px RMS does not change (no fields)
1475- cm_out_1 = optics.transport_covariance_matrix(cm_in, 2000.)
1476- for i in [2, 4, 6]:
1477- self.assertAlmostEqual(cm_in.get_element(i, i),
1478- cm_out_1.get_element(i, i), 1,
1479- msg="\nIN\n"+str(cm_in)+"\nOUT\n"+str(cm_out_1))
1480- cm_out_2 = optics.transport_covariance_matrix(cm_in, 3000.)
1481- for i in range(3):
1482- self.assertGreater(abs(cm_out_1.get_element(2*i+1, 2*i+2)), 1.)
1483- # check that we have some growth of correlation between e.g. x, px
1484- self.assertAlmostEqual(cm_out_1.get_element(3, 4),
1485- cm_out_1.get_element(5, 6), 2)
1486- for i in [2, 4, 6]:
1487- self.assertAlmostEqual(cm_in.get_element(i, i),
1488- cm_out_2.get_element(i, i), 1,
1489- msg="\nIN\n"+str(cm_in)+"\nOUT\n"+str(cm_out_2))
1490- # check no coupling between phase space planes
1491- for i in [2, 4, 5]:
1492- self.assertAlmostEqual(
1493- cm_in.get_element(i+1, i)-cm_out_1.get_element(i+1, i),
1494- cm_out_1.get_element(i+1, i)-cm_out_2.get_element(i+1, i),
1495- 1,
1496- msg="\nIN\n"+str(cm_in)+"\nOUT\n"+str(cm_out_2))
1497-
1498-
1499- def test_transport_phase_space_vector_no_planes(self):
1500- """
1501- Test maus_cpp.optics_model.Optics().transport_phase_space_vector() with
1502- no virtuals
1503- """
1504- self._set_geometry(self.no_planes_mod)
1505- optics = OpticsModel()
1506- psv_in = PhaseSpaceVector()
1507- try:
1508- optics.transport_phase_space_vector(psv_in, 2000.)
1509- self.assertTrue(False, "Should throw when no virtuals")
1510- except RuntimeError:
1511- pass
1512-
1513- def test_transport_phase_space_vector_bad_type(self):
1514- """
1515- Test maus_cpp.optics_model.Optics().transport_phase_space_vector() with
1516- no virtuals
1517- """
1518- self._set_geometry(self.good_mod)
1519- optics = OpticsModel()
1520- try:
1521- optics.transport_phase_space_vector("should be a psv", 2000.)
1522- self.assertTrue(False, "Should throw when wrong type passed")
1523- except TypeError:
1524- pass
1525-
1526- def test_transport_phase_space_vector(self):
1527- """Test maus_cpp.optics_model.Optics().transport_phase_space_vector()"""
1528- self._set_geometry(self.good_mod)
1529- optics = OpticsModel()
1530- psv_in = maus_cpp.phase_space_vector.create_from_coordinates \
1531- (0.1, 226., 1., 2., 3., 4.)
1532- psv_out = optics.transport_phase_space_vector(psv_in, 2000.)
1533- pz = (226.**2-105.6583715**2.-2.**2-4.**2)**0.5
1534- dz = 1000.
1535- t_expected = psv_in.get_t()+psv_out.get_energy()/pz/300.*dz # c=300.
1536- x_expected = psv_in.get_x()+psv_in.get_px()/pz*dz
1537- y_expected = psv_in.get_y()+psv_in.get_py()/pz*dz
1538- self.assertAlmostEqual(psv_out.get_t()/t_expected, 1, 3)
1539- self.assertAlmostEqual(psv_out.get_energy()/psv_in.get_energy(), 1., 5)
1540- self.assertAlmostEqual(psv_out.get_x()/x_expected, 1., 3)
1541- self.assertAlmostEqual(psv_out.get_px()/psv_in.get_px(), 1., 5)
1542- self.assertAlmostEqual(psv_out.get_y()/y_expected, 1., 3)
1543- self.assertAlmostEqual(psv_out.get_py()/psv_in.get_py(), 1., 5)
1544-
1545-if __name__ == "__main__":
1546- unittest.main()
1547-
1548
1549=== modified file 'tests/unit_tests.bash'
1550--- tests/unit_tests.bash 2017-02-20 14:14:11 +0000
1551+++ tests/unit_tests.bash 2017-06-08 17:10:31 +0000
1552@@ -41,7 +41,14 @@
1553 maus_coverage_extra="--with-coverage --cover-html --cover-html-dir=${MAUS_ROOT_DIR}/doc/python_coverage --cover-inclusive"
1554 fi
1555
1556-python ${MAUS_THIRD_PARTY}/third_party/install/bin/nosetests -v ${MAUS_ROOT_DIR}/build $maus_coverage_extra
1557+python ${MAUS_THIRD_PARTY}/third_party/install/bin/nosetests -v ${MAUS_ROOT_DIR}/build $maus_coverage_extra \
1558+--exclude-dir build/test_maus_cpp/test_optics/
1559+
1560+python ${MAUS_ROOT_DIR}/src/map/MapCppGlobalTrackMatching/_test_MapCppGlobalTrackMatching.py
1561+
1562+echo 'Testing optics separately as it corrupts globals singleton'
1563+python ${MAUS_THIRD_PARTY}/third_party/install/bin/nosetests -v ${MAUS_ROOT_DIR}/build/test_maus_cpp/test_optics/ $maus_coverage_extra
1564+
1565 if [ $maus_lcov ]; then
1566 if [ $maus_lcov -ne "0" ]; then
1567 echo Building lcov output
1568@@ -50,8 +57,6 @@
1569 fi
1570 fi
1571
1572-python ${MAUS_ROOT_DIR}/src/map/MapCppGlobalTrackMatching/_test_MapCppGlobalTrackMatching.py
1573-
1574 cd $here
1575
1576 echo
1577
1578=== modified file 'third_party/bash/21root.bash'
1579--- third_party/bash/21root.bash 2016-10-24 12:31:03 +0000
1580+++ third_party/bash/21root.bash 2017-06-08 17:10:31 +0000
1581@@ -59,11 +59,18 @@
1582 tar xvfz ${MAUS_ROOT_DIR}/third_party/source/${filename} -C ${MAUS_ROOT_DIR}/third_party/source > /dev/null
1583 mv ${MAUS_ROOT_DIR}/third_party/source/root ${MAUS_ROOT_DIR}/third_party/source/${directory}
1584
1585+
1586+ echo
1587+ echo "INFO: Patching:"
1588+ echo
1589+ cd ${MAUS_ROOT_DIR}/third_party/source/${directory}
1590+ patch -p1 < ${MAUS_ROOT_DIR}/third_party/source/gcc6.patch
1591+
1592+
1593+ echo
1594+ echo "INFO: Configuring:"
1595+ echo
1596 cd ${MAUS_ROOT_DIR}/third_party/build/${directory}
1597-
1598- echo
1599- echo "INFO: Configuring:"
1600- echo
1601 sleep 1
1602 # Tell cmake explicitly about third_party/install/include, third_party/install/lib and third_party/install/lib64 to look for headers and libs
1603 sed -i "s@include(MacroEnsureVersion)@include(MacroEnsureVersion)\ninclude_directories(${MAUS_ROOT_DIR}/third_party/install/include)\nlink_directories(${MAUS_ROOT_DIR}/third_party/install/lib ${MAUS_ROOT_DIR}/third_party/install/lib64)@" ${MAUS_ROOT_DIR}/third_party/source/${directory}/CMakeLists.txt
1604
1605=== modified file 'third_party/bash/47cdb_cpp.bash'
1606--- third_party/bash/47cdb_cpp.bash 2017-04-25 18:17:08 +0000
1607+++ third_party/bash/47cdb_cpp.bash 2017-06-08 17:10:31 +0000
1608@@ -1,6 +1,6 @@
1609 #!/usr/bin/env bash
1610
1611-version=1.0.3
1612+version=1.0.4
1613 directory="cdb-C++.v${version}"
1614 filename="cdb.client.api-cpp.v${version}.tgz"
1615 md5file=${filename}.md5
1616@@ -17,7 +17,7 @@
1617
1618 # safer in any case to get the source from micemine
1619 # v1.0.3
1620-url=http://micewww.pp.rl.ac.uk/attachments/8738/${filename}
1621+url=https://micewww.pp.rl.ac.uk/attachments/download/8954/${filename}
1622
1623 echo
1624 echo 'INFO: Installing third party library CDB-C++' $version
1625
1626=== modified file 'third_party/build_all.bash'
1627--- third_party/build_all.bash 2017-04-23 22:27:43 +0000
1628+++ third_party/build_all.bash 2017-06-08 17:10:31 +0000
1629@@ -73,13 +73,14 @@
1630 # Make the numpy includes findable
1631 old_dir=`pwd`
1632 cd ${MAUS_THIRD_PARTY}/third_party/install/include
1633- ln -s ../lib/python2.7/site-packages/numpy/core/include/numpy numpy
1634+ ln -sf ../lib/python2.7/site-packages/numpy/core/include/numpy numpy
1635 cd ${old_dir}
1636
1637 ${MAUS_ROOT_DIR}/third_party/bash/51xboa.bash
1638 ${MAUS_ROOT_DIR}/third_party/bash/42libxml2.bash -j $MAUS_NUM_THREADS
1639 ${MAUS_ROOT_DIR}/third_party/bash/43libxslt.bash -j $MAUS_NUM_THREADS
1640 ${MAUS_ROOT_DIR}/third_party/bash/44cdb.bash
1641+ ${MAUS_ROOT_DIR}/third_party/bash/54flex.bash -j $MAUS_NUM_THREADS
1642 ${MAUS_ROOT_DIR}/third_party/bash/46gsoap.bash
1643 ${MAUS_ROOT_DIR}/third_party/bash/47cdb_cpp.bash
1644
1645@@ -102,7 +103,6 @@
1646 # ${MAUS_ROOT_DIR}/third_party/bash/82heprep.bash
1647
1648 # Doxygen for code documentation, requires a recent version of flex
1649- ${MAUS_ROOT_DIR}/third_party/bash/54flex.bash -j $MAUS_NUM_THREADS
1650 ${MAUS_ROOT_DIR}/third_party/bash/55doxygen.bash -j $MAUS_NUM_THREADS
1651
1652 # MAUS should now build okay - now for the test and execution environment
1653
1654=== removed file 'third_party/source/cdb.client.api-cpp.v1.0.3.tgz.md5'
1655--- third_party/source/cdb.client.api-cpp.v1.0.3.tgz.md5 2017-04-25 15:09:46 +0000
1656+++ third_party/source/cdb.client.api-cpp.v1.0.3.tgz.md5 1970-01-01 00:00:00 +0000
1657@@ -1,1 +0,0 @@
1658-042024d29d62c23d1fa72f6002820574 cdb.client.api-cpp.v1.0.3.tgz
1659
1660=== added file 'third_party/source/cdb.client.api-cpp.v1.0.4.tgz.md5'
1661--- third_party/source/cdb.client.api-cpp.v1.0.4.tgz.md5 1970-01-01 00:00:00 +0000
1662+++ third_party/source/cdb.client.api-cpp.v1.0.4.tgz.md5 2017-06-08 17:10:31 +0000
1663@@ -0,0 +1,1 @@
1664+6bd9f083ab1507eb41dd5c8e08ae0253 cdb.client.api-cpp.v1.0.4.tgz
1665
1666=== added file 'third_party/source/gcc6.patch'
1667--- third_party/source/gcc6.patch 1970-01-01 00:00:00 +0000
1668+++ third_party/source/gcc6.patch 2017-06-08 17:10:31 +0000
1669@@ -0,0 +1,74 @@
1670+diff --git a/cint/cint/Module.mk b/cint/cint/Module.mk
1671+index 0293321..99a729b 100644
1672+--- a/cint/cint/Module.mk
1673++++ b/cint/cint/Module.mk
1674+@@ -165,6 +165,10 @@ ifeq ($(GCC_MAJOR),5)
1675+ CINTS2 := $(filter-out $(MODDIRSD)/libstrm.%,$(CINTS2))
1676+ CINTS2 += $(MODDIRSD)/gcc4strm.cxx
1677+ endif
1678++ifeq ($(GCC_MAJOR),6)
1679++CINTS2 := $(filter-out $(MODDIRSD)/libstrm.%,$(CINTS2))
1680++CINTS2 += $(MODDIRSD)/gcc4strm.cxx
1681++endif
1682+ ifneq ($(CLANG_MAJOR),)
1683+ CINTS2 := $(filter-out $(MODDIRSD)/libstrm.%,$(CINTS2))
1684+ CINTS2 += $(MODDIRSD)/gcc4strm.cxx
1685+@@ -207,6 +211,9 @@ IOSENUMC := $(CINTDIRIOSEN)/iosenum.cxx
1686+ ifneq ($(CLANG_MAJOR),)
1687+ IOSENUMA := $(CINTDIRIOSEN)/iosenum.$(ARCH)3
1688+ else
1689++ifeq ($(GCC_MAJOR),6)
1690++IOSENUMA := $(CINTDIRIOSEN)/iosenum.$(ARCH)3
1691++else
1692+ ifeq ($(GCC_MAJOR),5)
1693+ IOSENUMA := $(CINTDIRIOSEN)/iosenum.$(ARCH)3
1694+ else
1695+@@ -221,6 +228,7 @@ endif
1696+ endif
1697+ endif
1698+ endif
1699++endif
1700+
1701+ # used in the main Makefile
1702+ ALLHDRS += $(CINTHT) $(CINTINCLUDES)
1703+@@ -355,6 +363,9 @@ endif
1704+ ifeq ($(GCC_MAJOR),5)
1705+ $(call stripsrc,$(CINTDIRSD)/gcc4strm.o): CINTCXXFLAGS += -Wno-strict-aliasing
1706+ endif
1707++ifeq ($(GCC_MAJOR),6)
1708++$(call stripsrc,$(CINTDIRSD)/gcc4strm.o): CINTCXXFLAGS += -Wno-strict-aliasing
1709++endif
1710+
1711+
1712+ $(MAKECINTO) $(CINTO): $(CINTCONF) $(ORDER_) $(CINTINCLUDES)
1713+@@ -389,8 +400,12 @@ endif
1714+ ##### configcint.h
1715+ ifeq ($(CPPPREP),)
1716+ # cannot use "CPPPREP?=", as someone might set "CPPPREP="
1717++ifeq ($(GCC_MAJOR),6)
1718++ CPPPREP = $(CXX) -std=c++98 -E -C
1719++else
1720+ CPPPREP = $(CXX) -E -C
1721+ endif
1722++endif
1723+
1724+ include $(CINTCONFMK)
1725+ ##### configcint.h - END
1726+diff --git a/cmake/modules/SetUpLinux.cmake b/cmake/modules/SetUpLinux.cmake
1727+index cc389b4..01b3b62 100644
1728+--- a/cmake/modules/SetUpLinux.cmake
1729++++ b/cmake/modules/SetUpLinux.cmake
1730+@@ -69,7 +69,12 @@ if(CMAKE_COMPILER_IS_GNUCXX)
1731+ set(CMAKE_C_FLAGS_PROFILE "-g3 -fno-inline -ftest-coverage -fprofile-arcs")
1732+
1733+ #Settings for cint
1734+- set(CPPPREP "${CXX} -E -C")
1735++ if (GCC_MAJOR EQUAL 6)
1736++ set(CPPPREP "${CXX} -std=c++98 -E -C")
1737++ else()
1738++ set(CPPPREP "${CXX} -E -C")
1739++ endif()
1740++
1741+ set(CXXOUT "-o ")
1742+ set(EXPLICITLINK "no") #TODO
1743+

Subscribers

People subscribed via source and target branches