From 89cfe76513f824c740f0408b93caa189d1ff3bd0 Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Mon, 19 Jul 2021 14:54:01 -0400 Subject: [PATCH 1/9] Avoid keyword arguments to Record.check_field. Since commit 21764cf09ef7b1af666710518664be90bd05e2b5, the optional parameter to wfdb.io.record.BaseRecord.check_field is called "required_channels", not "channels". The semantics appear equivalent. Several callers were still referring to the old name "channels", while most callers simply use positional arguments. Change all callers to use positional arguments for consistency. --- wfdb/io/_signal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wfdb/io/_signal.py b/wfdb/io/_signal.py index 405a4031..56b673fa 100644 --- a/wfdb/io/_signal.py +++ b/wfdb/io/_signal.py @@ -295,7 +295,7 @@ def set_p_features(self, do_dac=False, expanded=False): self.e_p_signal = self.dac(expanded) # Use e_p_signal to set fields - self.check_field("e_p_signal", channels="all") + self.check_field("e_p_signal", "all") self.sig_len = int( len(self.e_p_signal[0]) / self.samps_per_frame[0] ) @@ -361,7 +361,7 @@ def set_d_features(self, do_adc=False, single_fmt=True, expanded=False): if expanded: # adc is performed. if do_adc: - self.check_field("e_p_signal", channels="all") + self.check_field("e_p_signal", "all") # If there is no fmt set it, adc_gain, and baseline if self.fmt is None: @@ -393,7 +393,7 @@ def set_d_features(self, do_adc=False, single_fmt=True, expanded=False): self.d_signal = self.adc(expanded) # Use e_d_signal to set fields - self.check_field("e_d_signal", channels="all") + self.check_field("e_d_signal", "all") self.sig_len = int( len(self.e_d_signal[0]) / self.samps_per_frame[0] ) From 5ff3563ae1fed571c5b5342df4acd524ed574dde Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 20 Jul 2021 12:29:32 -0400 Subject: [PATCH 2/9] multi_to_single: set samps_per_frame attribute. When reading a multi-segment record, the samps_per_frame attribute must be copied from the layout segment into the resulting flattened record. (Unlike most other signal attributes, samples per frame must be uniform for a particular signal. The layout header must be used to determine the correct number of samples per frame for signals that are not present in the selected segments.) --- wfdb/io/record.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/wfdb/io/record.py b/wfdb/io/record.py index cbdae36e..ee332e14 100644 --- a/wfdb/io/record.py +++ b/wfdb/io/record.py @@ -1300,7 +1300,14 @@ def multi_to_single(self, physical, return_res=64): # Figure out single segment fields to set for the new Record if self.layout == "fixed": # Get the fields from the first segment - for attr in ["fmt", "adc_gain", "baseline", "units", "sig_name"]: + for attr in [ + "fmt", + "adc_gain", + "baseline", + "units", + "sig_name", + "samps_per_frame", + ]: fields[attr] = getattr(self.segments[0], attr) else: # For variable layout records, inspect the segments for the @@ -1311,9 +1318,14 @@ def multi_to_single(self, physical, return_res=64): # must have the same fmt, gain, baseline, and units for all # segments. + # For either physical or digital conversion, all signals + # of the same name must have the same samps_per_frame, + # which must match the value in the layout header. + # The layout header should be updated at this point to - # reflect channels. We can depend on it for sig_name, but - # not for fmt, adc_gain, units, and baseline. + # reflect channels. We can depend on it for sig_name and + # samps_per_frame, but not for fmt, adc_gain, units, and + # baseline. # These signal names will be the key signal_names = self.segments[0].sig_name @@ -1325,6 +1337,7 @@ def multi_to_single(self, physical, return_res=64): "adc_gain": n_sig * [None], "baseline": n_sig * [None], "units": n_sig * [None], + "samps_per_frame": self.segments[0].samps_per_frame, } # For physical signals, mismatched fields will not be copied @@ -1346,7 +1359,19 @@ def multi_to_single(self, physical, return_res=64): reference_fields[field][ch] = item_ch # mismatch case elif reference_fields[field][ch] != item_ch: - if physical: + if field == "samps_per_frame": + raise ValueError( + "Incorrect samples per frame (%s != %s) " + "for signal %s in segment %s of %s" + % ( + item_ch, + reference_fields[field][ch], + signal_names[ch], + seg.record_name, + self.record_name, + ) + ) + elif physical: mismatched_fields.append(field) else: raise Exception( From 6cd18baad3f3036da140dd6a5d4de046640d3bc3 Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 20 Jul 2021 15:56:10 -0400 Subject: [PATCH 3/9] multi_to_single: add expanded argument. When reading a multi-segment record, the multi_to_single function is used to stitch the segments together into a virtual single-segment record. To enable this to work in expanded (non-smooth-frames) mode, we want to combine the 'e_p_signal' or 'e_d_signal' arrays from the individual segments, rather than 'p_signal' or 'd_signal'. --- wfdb/io/record.py | 58 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/wfdb/io/record.py b/wfdb/io/record.py index ee332e14..a1f6c059 100644 --- a/wfdb/io/record.py +++ b/wfdb/io/record.py @@ -1269,7 +1269,7 @@ def _arrange_fields( self.n_seg = len(self.segments) self._adjust_datetime(sampfrom=sampfrom) - def multi_to_single(self, physical, return_res=64): + def multi_to_single(self, physical, return_res=64, expanded=False): """ Create a Record object from the MultiRecord object. All signal segments will be combined into the new object's `p_signal` or @@ -1283,6 +1283,11 @@ def multi_to_single(self, physical, return_res=64): return_res : int, optional The return resolution of the `p_signal` field. Options are: 64, 32, and 16. + expanded : bool, optional + If false, combine the sample data from `p_signal` or `d_signal` + into a single two-dimensional array. If true, combine the + sample data from `e_p_signal` or `e_d_signal` into a list of + one-dimensional arrays. Returns ------- @@ -1386,18 +1391,31 @@ def multi_to_single(self, physical, return_res=64): # Figure out signal attribute to set, and its dtype. if physical: - sig_attr = "p_signal" + if expanded: + sig_attr = "e_p_signal" + else: + sig_attr = "p_signal" # Figure out the largest required dtype dtype = _signal._np_dtype(return_res, discrete=False) nan_vals = np.array([self.n_sig * [np.nan]], dtype=dtype) else: - sig_attr = "d_signal" + if expanded: + sig_attr = "e_d_signal" + else: + sig_attr = "d_signal" # Figure out the largest required dtype dtype = _signal._np_dtype(return_res, discrete=True) nan_vals = np.array([_signal._digi_nan(fields["fmt"])], dtype=dtype) + samps_per_frame = fields["samps_per_frame"] + # Initialize the full signal array - combined_signal = np.repeat(nan_vals, self.sig_len, axis=0) + if expanded: + combined_signal = [] + for nan_val, spf in zip(nan_vals[0], samps_per_frame): + combined_signal.append(np.repeat(nan_val, spf * self.sig_len)) + else: + combined_signal = np.repeat(nan_vals, self.sig_len, axis=0) # Start and end samples in the overall array to place the # segment samples into @@ -1408,9 +1426,16 @@ def multi_to_single(self, physical, return_res=64): # Copy over the signals directly. Recall there are no # empty segments in fixed layout records. for i in range(self.n_seg): - combined_signal[start_samps[i] : end_samps[i], :] = getattr( - self.segments[i], sig_attr - ) + if expanded: + signals = getattr(self.segments[i], sig_attr) + for ch in range(self.n_sig): + start = start_samps[i] * samps_per_frame[ch] + end = end_samps[i] * samps_per_frame[ch] + combined_signal[ch][start:end] = signals[ch] + else: + combined_signal[start_samps[i] : end_samps[i], :] = getattr( + self.segments[i], sig_attr + ) else: # Copy over the signals into the matching channels for i in range(1, self.n_seg): @@ -1424,9 +1449,18 @@ def multi_to_single(self, physical, return_res=64): for ch in range(self.n_sig): # Copy over relevant signal if segment_channels[ch] is not None: - combined_signal[ - start_samps[i] : end_samps[i], ch - ] = getattr(seg, sig_attr)[:, segment_channels[ch]] + if expanded: + signals = getattr(seg, sig_attr) + signal = signals[segment_channels[ch]] + start = start_samps[i] * samps_per_frame[ch] + end = end_samps[i] * samps_per_frame[ch] + combined_signal[ch][start:end] = signal + else: + combined_signal[ + start_samps[i] : end_samps[i], ch + ] = getattr(seg, sig_attr)[ + :, segment_channels[ch] + ] # Create the single segment Record object and set attributes record = Record() @@ -1436,9 +1470,9 @@ def multi_to_single(self, physical, return_res=64): # Use the signal to set record features if physical: - record.set_p_features() + record.set_p_features(expanded=expanded) else: - record.set_d_features() + record.set_d_features(expanded=expanded) return record From d330a4a9e0cb9be224b23df9d85ca8656299dfd4 Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 20 Jul 2021 15:57:10 -0400 Subject: [PATCH 4/9] multi_to_single: rearrange for readability. --- wfdb/io/record.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/wfdb/io/record.py b/wfdb/io/record.py index a1f6c059..e7c82aa9 100644 --- a/wfdb/io/record.py +++ b/wfdb/io/record.py @@ -1426,16 +1426,16 @@ def multi_to_single(self, physical, return_res=64, expanded=False): # Copy over the signals directly. Recall there are no # empty segments in fixed layout records. for i in range(self.n_seg): + signals = getattr(self.segments[i], sig_attr) if expanded: - signals = getattr(self.segments[i], sig_attr) for ch in range(self.n_sig): start = start_samps[i] * samps_per_frame[ch] end = end_samps[i] * samps_per_frame[ch] combined_signal[ch][start:end] = signals[ch] else: - combined_signal[start_samps[i] : end_samps[i], :] = getattr( - self.segments[i], sig_attr - ) + start = start_samps[i] + end = end_samps[i] + combined_signal[start:end, :] = signals else: # Copy over the signals into the matching channels for i in range(1, self.n_seg): @@ -1446,21 +1446,20 @@ def multi_to_single(self, physical, return_res=64, expanded=False): segment_channels = _get_wanted_channels( fields["sig_name"], seg.sig_name, pad=True ) + signals = getattr(seg, sig_attr) for ch in range(self.n_sig): # Copy over relevant signal if segment_channels[ch] is not None: if expanded: - signals = getattr(seg, sig_attr) signal = signals[segment_channels[ch]] start = start_samps[i] * samps_per_frame[ch] end = end_samps[i] * samps_per_frame[ch] combined_signal[ch][start:end] = signal else: - combined_signal[ - start_samps[i] : end_samps[i], ch - ] = getattr(seg, sig_attr)[ - :, segment_channels[ch] - ] + signal = signals[:, segment_channels[ch]] + start = start_samps[i] + end = end_samps[i] + combined_signal[start:end, ch] = signal # Create the single segment Record object and set attributes record = Record() From 8098338badd8aa66675c9f86a661c5c541053748 Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 20 Jul 2021 15:58:25 -0400 Subject: [PATCH 5/9] rdrecord: allow smooth_frames=False for multi-segment records. When reading a multi-segment, multi-frequency record, we want to have the option of reading each signal at its original sampling frequency, which requires using smooth_frames=False. Previously this simply wasn't allowed, either with or without multi-to-single conversion. To do this, we need to ensure each segment is loaded in the appropriate (smooth or non-smooth) mode (which formerly would have failed if certain segments *didn't* contain multiple samples per frame.) After loading the segments, we must invoke multi_to_single, if desired, in the appropriate mode. --- wfdb/io/record.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/wfdb/io/record.py b/wfdb/io/record.py index e7c82aa9..e67acc24 100644 --- a/wfdb/io/record.py +++ b/wfdb/io/record.py @@ -510,13 +510,6 @@ def check_read_inputs( "return_res must be one of the following when physical is True: 64, 32, 16" ) - # Cannot expand multiple samples/frame for multi-segment records - if isinstance(self, MultiRecord): - if not smooth_frames: - raise ValueError( - "This package version cannot expand all samples when reading multi-segment records. Must enable frame smoothing." - ) - def _adjust_datetime(self, sampfrom): """ Adjust date and time fields to reflect user input if possible. @@ -4226,6 +4219,7 @@ def rdrecord( channels=seg_channels[i], physical=physical, pn_dir=pn_dir, + smooth_frames=smooth_frames, return_res=return_res, ) @@ -4242,7 +4236,9 @@ def rdrecord( # Convert object into a single segment Record object if m2s: record = record.multi_to_single( - physical=physical, return_res=return_res + physical=physical, + expanded=(not smooth_frames), + return_res=return_res, ) # Perform dtype conversion if necessary From 90b8e3b86f006c67f837be8a49dd85c576b12855 Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 12 Oct 2021 17:09:44 -0400 Subject: [PATCH 6/9] Test reading fixed-layout multi-frequency signals. This test case uses an excerpt of record mimicdb/041/, which is a fixed-layout record with three signals at 500 Hz (four samples per frame) and four signals at 125 Hz (one sample per frame). --- sample-data/multi-segment/041s/041s.hea | 3 ++ sample-data/multi-segment/041s/041s01.dat | Bin 0 -> 24000 bytes sample-data/multi-segment/041s/041s01.hea | 9 +++++ sample-data/multi-segment/041s/041s02.dat | Bin 0 -> 24000 bytes sample-data/multi-segment/041s/041s02.hea | 9 +++++ tests/target-output/record-multi-fixed-d.gz | Bin 0 -> 26883 bytes tests/test_record.py | 35 ++++++++++++++++++++ 7 files changed, 56 insertions(+) create mode 100644 sample-data/multi-segment/041s/041s.hea create mode 100644 sample-data/multi-segment/041s/041s01.dat create mode 100644 sample-data/multi-segment/041s/041s01.hea create mode 100644 sample-data/multi-segment/041s/041s02.dat create mode 100644 sample-data/multi-segment/041s/041s02.hea create mode 100644 tests/target-output/record-multi-fixed-d.gz diff --git a/sample-data/multi-segment/041s/041s.hea b/sample-data/multi-segment/041s/041s.hea new file mode 100644 index 00000000..74844c25 --- /dev/null +++ b/sample-data/multi-segment/041s/041s.hea @@ -0,0 +1,3 @@ +041s/2 7 125 2000 8:26:04 26/10/1994 +041s01 1000 +041s02 1000 diff --git a/sample-data/multi-segment/041s/041s01.dat b/sample-data/multi-segment/041s/041s01.dat new file mode 100644 index 0000000000000000000000000000000000000000..221d4014abbaef7ae1a0d466cd2184c0639db97f GIT binary patch literal 24000 zcmYjZ30PFs+drU|C<8NKVmiYBCN2$2EdDJ~RIp6U48?@hz!g`_Ow5!_1vhXdH&PME z1rY%^kjvtdnA|~gK~pYnxTMT5iI$?5^Zo8QBVW&RAD?>X<(zZRdC&WM*SnAG+e5N! zE%oIzJB=hJl0*leQ^&O%c9N~@NK&<9Ti=K;8c8FbZoXqb(ItkGK?6wtd!bdX0g)IypCpd(op(_8QxN&+ zBl1z1$CHq*o8m}ZB8i*jyCTqaaUas#n|L-7ThE3RFJfCytAFs_R^$48C(^EoKGvJ{ zdUHxSEib3li+wZG^zpUyQWZTPtGC;538syGrE zLcAh;cLr(VFVicR=_S35R6!bDh^;Mg@%LTd#_9VDR6I+|8%d%U@nUq__P&dYoE8<) zf^3@MLgMn(dRt=aLcDGT$Bc0PX(!#ji)ID+C8mW0L@N87b|g6HjPr^^^u!rj6%cSX zuIqm6Kc-$8+_6K4wHN6nOcCS}9{qP}B#FeUjrDmL(qS_uJwcDeI=bYm1F;w{65{7` zXmp2Nc{C@7=GbYHulmJ-7)KJ@`po^J!~R3G;3zFj^pAAudKHI@eY@k`{lgANifQRd zdZx@{Q>;f2_7n38u6LX}l>J7}{zlJudU$$zs4*{|&91xdI-fs7&){j&G&O1J7(L`$ z*O_~rt2w<&Q-vplgy0Ex9XQeXE~gi2s_=072d>>*oE!c_&*1b9uFhwiWKPe}6lQ2L zuzu|73!U9e5BoQCj9&;M{-joCr}ofco#*KJLQMwa_rg!-bawgfzD9cS4|=IkQ;2y% z#85|dcEjC2zCx@2q&1*p96s+JUF*kg<8RZtN3@>tTj|?%tyj3sv(RTRX)~BHKI8Y= zs3Tq75(%+wL)s>5l9M&_+4x?`sz)b%Hnt=74nz(5P@4+SArh-pr@!_|b0GHZNZay; zm=mjtPrP@(P2OrlS{F5Y#x_({(|XA5DplxO?@Sv@a})h1%~%~}3QVO5 zskD5J{4&sc_fu+qMDI45V&ZEnvK4vGUMK&0$16>u*Q@Cj$rKZ2PGR)wjq6em8;ePx3ENCRxAIDs=#>h3B3mr) zB&C6v3TtZa!1>pQvD{w%3tW7bM&!`f1283KZFhUXqU8S zieaTMnSWnB>Z$+Px;ss2B+k|nv`d;DYFPc)eMt}hi}})=ImYTtb6|xOx=RY}Wmx-l zsJTzX(rhe7OsE!PHA3btsq4FjO|v7S{tjK)PwbaaV;fT(7E_$EQ+iu%*xKMfy2wKt zC8Z@v`S&aPC5ZJqjn5nmJGW^%7Lq9JPo}wQj?@@qF4|$d<7D{N-SX%>%?Wb!s;1d$ znvhMaw;OA8hJ(B4#uU1e?-;+Qn~m4K49Aw!C5z|+P^xJ;my->~>-`O7bLq@UbZj-P zuBY|_6kqix-;7KXlzB$8gEUuJwT$#6N2Cak9!8KJIE{Uhycpx>lL z#%J>lwYl^}F%`0Jh1wcpL!eJA_1{VDR~jB4qj}jh>q2pSN~H!w{!r%=fo=ZJ+(mEyC4Y!m357#dzJR(CR`fM`p+qNR&@K@P*{$Dh+NA#SlRCq0cL z6@i-hQKrGigF1gp*XGiyHSt5wPBB1qqcuZEnvMxU-S5-at%?21XW1!f*X(RU%4xzd z*|99h=WSy9l3IS;cFjAxAc3Z0qdu0u2K^DeT|=)27Qc!Wv$04_JwO)9f_hwK`l`If zHdIOj5qj?-cRo!ptrl3yoWcg;Y5BhMi$6|mKp3(jHCI`6`ld7BKQLKkL`&I?cF_DCn_Ag5c zQr8oUi99YB+`O}Y!R5kMycK+IiGkiHxBn!U0*f;&8`IA^aR zA&D&cp3Dt2hozW{ToiubQGShK>N|w={~z&-fBDe9vThY2PQF?nK+vtX4NPar$oGbA7x?C(^-@w8J<}&7Kf-JbQhO4_zO&vb_F> zT7qbJ5Vg{G_+HAoT&OOtW;h#8V`FJJA7_&9xsNsb&eBum zwA7P&s;MXAuMYA(Ve7QHgbD%`f)xHB&ad&^`>RvZ30ioZ9&0i;;o;-g1+VGu9Dj@+ zJ5CF+NDRgK3xj7QIZr=9g;H8xXRfL;S8;lBaL{Sz@h9o2lc3{$sal~s+QtO8z3V)( zlnN!ZR2je7O8=ivB#`FFZ5>+9@;_r<(ye^NR92iK2fr(S#jQx+L2~ZmNlfJIKra8HDe8dgKJ}cu`>b0()cXZNmIvZcn|9E8^*JUM|&Tr^J zP39uDKh=+P1rs$c98as7)t)p6hlrmp>8e_5-r;!q-*YV2-Oo}xb36qzmc+)XFVH<3 zq;}$XYUPK%vefU@y||-yYM@V_(-)o;<6HT6>7FgoJHMbW@PyL@<-OSY({zvB^&S4D z|1?qy_AP;y^YORoYEHR!sHcza(OQ^u*))N_*EU_%RM!qSX!T`!5rdSo#p9>#x?%^{ z4pmeXspv)GB8eB@=N-C(MLK5?E9rT5vlOL@CtbHaR_A<O)@So2HdOre2ccjA)1#*^ZsKexa`;YM{7HR zh$mW8*rb7#sPG@qx%g_|&8Gz?=&7L^eW1n;_m|O$omN*%n?527?KIKcE(#$oIjTob zy0|}4kA3OB8RJK50_$mlx*_v`s=B&Mw}Jlk^GA_JlJ8~74y?`hHkKbyojcd1XTOMr zqa*x08;ZircKw9=nZ+slRYy;E@e)Em-sj)0(WH+tr=%2L=q@JgRb`y*^1&RZ>L{C9 zC=E{DRZglzIak}$onjA;cV8m9# z-XLB(RMCHR`EVs&zKkwSBl&njm_4~g75=(Q-=FA`1iA>se3HiO&$tb$P)BY5MRXA! zn8#_Pg40*4dUw?hN}x*;>FW9J>OxIm8k=RAs%xP3C?1PbLsRMbY_$(>`C}0fUKkr951KL(T@9puFj;w)xlMZC%dpy8yYG9@|||v zAM}Bl{*%$6DZVP!&L$1e5H6pO*G4_3&&>2uW^vK|%I;i`g{kZpXh+?pH8<%EfN6bA zCrB5j9;_NZUmJFV-ndC?0H%`3j@kKM!K!WZwEb)8?Yp#&`86CDygpPtoul=F5et(w z#++GYZsPmwryD)tB@V?iqNc%r}5pO@z8~QDQW;1$PnAb1i_Q(2@k4KQGaz_^zOEo{u z?Or9r?9(QY>EDnA7$=sd!tcP5IeFI(wqKG!maigfVcFs*5b;xz_w#}FlQ)pm&15U? zFDzc>r=Q-i7vrC|7Y)$PSWwf9L45v`taZZz3n@IxQpym z5YSSM#pBhIf=Bjy{W6VgO(p9w2!`VJ+o|BOBVO08AxUs)q48jJfew?82FEOTeP%A1 zK7m9j7B4M_{NM@jol^8VJDdz1L_T5~lG9zr`cCO0uMZ&JJ%|V13#yp=gWvg%{Y9Sd zN;-EWPR!1<>iM61M-FWM%AUMMEKRVq!O!LGN8bT2nuDKH%MG&seSxNBVYLVQF)Lo(H7jP_RzWp>Mt2=qGm`L0=WoV{D(ZIe#0s+Glq} z;3ghyGCT+_Z`XZFmfy|i^lX}%`er>jKARfvZsv6MzSVr4Klw}wzPAW;;4db{6r3L6 z<2(J{MBp!Q4dY{>8pOd35#p{wnBHCy^!`r})=B#j=U@f1(AVkZaMH$SZZ|LFGX+D7-`A2$d;{toM=nhQu@zG;l4&xAQ%FCO@2AxkK8Bp_Mh}ps8j(xgV`ZS zC*>#iE~fuMF9MS6%$c})KryT;S3a3|aRczkNULzag5KCayW}6cUHl1g06;D1*$l+7 z)J?K)#jS7P%-*375*7UkJ*L=!t4%kj-kMNPpZ-Iepa$V=^7lC#M@!mU^zL1H7dIjsc9cc2D-w+h+euEf^ae~s zrXOONbk(mg4mw@a7QvYcdWO*x_7!17tYriD&jcs@NrT~@-9@~xKEq=khwrE_G-$% zDJ40_D=*zp54!4(8>iSCsWhm{90UG6m6a<0g8rfBvCg1|%tk56)|k4c3QI6zDd8Vr0!s4Q3e_IuH`|XIRz$J3Pa(9l2=0Iu}YekK~tF?R-9S9^7lpuV`afw zx-yY2g))IqF}osUp3(hIW$seC6i>aQ3v*_bc+PBNpJ$Z^fWM3BLi~A)K8!VvuoL&i z(|O;}*-SIIa6LJ}IJ1kmXC|FKolZ|wM+bRah5m=sePvwvzWD1bI%ff00)Og>$0kXU zmi$r1f{(<^HFWcCnse1J@~LxEg%T%B`^?xdMBG(C3lVxsvt*~#N^v9v2lufQ8ZK^w zJq&%7FXc-n#I+Qy9xNS-5;q)X_En0x3idhE!y$c4ZeNQ@u&-b;VIOb=+)wv2t)D2y zA7Oe4MA(fS2j4gSJ6W6zy;P>S9=N0l{Jpx#5tGCb6;!-LuQ$4d2igFnDiE@8m2)SG zA4>G@Lx`EBI)ULM{-l%Y?HJJ=b}a5!tfFs$BMQDasiMb;ZDoeDT)%NVbyVez5zHKC zaZ=b)hMS4)RZqVbu5g@H-qd2nH9MVqq)-f;{eT2;3yN7mX=>fTkwV6Yq<<(GiZ{ZJ zG5aU&BVFX@!s>7m1*pY1aIQH$RX68T;ah+&pcc#aA}*ZX)^%m5FdpCwsO9_|H)pu+ z3KoU}d;zt1BUqT6p6`0Rukb&BFCZ2C5Gwv&4_trmBXr|9i}fHf$>@LeSD{^S52OawDj*sohoT~n$w=e0%^pzE7+qkuNKUnTbJOH(dl4s5l7OZtsXB<2X z@CDT3+@aq<#M8sA!@%6V0N-cS%?hF892-J6(6U; z;nlXxRbYmz%j^Uz4puni{hXQ1=LIL%pZJdqhv>zb>$o5KU))^eppVSl$o){Twctx+ zv!#3HX0D&Xk9)!A?cIFcl(C)f0~XoB-?91nfsCEl2fQzgjh0t_AwQguk%^!*roi>b zEAw$~$}gQV_9G~bp>QrOYZWfM()pIdh#Y^ER@h9M)Bwu$c#W7vELa#udV?F%nr^;uICG9}O1Ad4i=Z}?he=N}; zd2x{{5oQdIL6mjM8v{z-73q1TJiw{Q6&rts{LSBjJNJwEp>Y0L@)t*hUM+sHA}5T0 zmhAhZ5b(y%#9_H`{@HSeFNFR@R1j$mySdi=oNan-5QelR0V~K2Fnck(qMD}8HvQ!& zgpbwKF7xXFO%h_M4r-{1sg-7#ZoVoWTM;s)a+GguLtRX5W0bKvR(LhTbje&iB`9LZ z>(IP8Qm1S&7S3#ZamqB)?|&7?^$f^p+jVw7F*a4Kzfh@(6|1M3%AOQ2c%T{IL^jWn zB!tvpl?9qJCz*~l7B7h)9V}FY-&EJ^S=Std3ld|>X)az_MEC4azyijDqPn5D#+kM| z2{9uR~28e-a8-(A8_{Mz(KO{{GV68-$`wG<7rG3jP)x|DSX< zT`1d5f7waXxt#FvKaeiw2&Z<_j9=+KCRg>C6yv`y{e4V0y`N_1&|EgYRnK=bbt@H4 z<$?4b-~pUnPd4Ik0g+fO{$!GC`Ch?gBiXottY>kOIKKWY*P34i`xLTz69YHoCh&vY$O@I$s;!0Bb<#Nx7#PMK1Ui!Mhqvz z7JF=J(nK?VIpm^GuvziAL8dldeoWY5trstXYV$o zWA1r((%G5Vhbi&uc&2r$UEGEo%dKe5;>MZgI+$vpLq&9O3z>81H#oU<^lmr}LIep! zJa4&u^ild5=tKA&%zm@d8+^LIz55KD1>{3{+<^06@abUOedatpS3%Dr$bkF8^m9LBT2Ir`xVtU6ur#Eu*F2$JBh@B8NZT&AM04{9J`ou}>8KRENbR z>o4#_IVd~x26yH-cwNu5AeamYgWBOD2mY|;Cs~;Ft_NdK_-g=`EXspX%i+)dlZxI?O6Ws5t*c`T4Q}S560rz;xmCLY4jd1>HgCxXjk0 zsPx^ct{3usk%Yy)=K6~BuTy!&<@e$D8v3Dy|3{UdL;e8xgLU))K%~VUo2&9WkT>KJ zeQc&rTPDR&(^OtV@V1Lg^3 z%SrVZ4g7aS*#cw%sZ(W-(ZcUP`n`85B${PrV*#mij95>*0m9{TqkIQOgcq6Z0I3P0 zrl>e&vguzxp~h}-d7ps1YOx$C+LYoqY-nbagUa%jJsm2T6Zth(YV<`VDj=__3Ls|9{fO zd~q;vb_?Ck&b^$)nIrwAiZXHdPMWcYy$()<^Bbhv^I`@jPx}1yey7E z{26{LPQ1mRax<;CA$|#vMM#ay3CGROrfavvksN24oTI1%c0%Gia)-O(uv7Hxd0K^) z!~f#?TrGc6Cl0zqtFO}=Orl)CkDuDftL}+`2qxDk_L#DhT)NuGSMG|QxQ~yh8A!pL zU*Jf-jjHP{vEwt^WJB5_uVH7C&vEdz{p=d?ZSK#48AU!EH(%Nx{Zn|s{aK_n z4)EIk=@sGe`^2|5K?M;X1W;R{({;Nj)P#~@BS{pBYLHZA{1wx6pH~VOVo2-^G8>4A zH|68s)Fqr1PQ{Tq-;((iYW;jo219cx#5L=raBLw-SW1%SYnq<;B_hs%1*~(eDiN}i z$;K_@mpuQtG7nF-s)`ENhGJnS_h(VW(xj=vA~D5F@AgH)Mg)x!B5rc`R67;2dDFW4 zyjvzDA!xjsEKk-%57j8Rj4h4y@u(6OE+X@0kO@OI(MZAY^IGTAy+N4s6&W>*gd)9; z{hCB~$w`zcs_%vq_T-Il;l1eFA?h`5Jz!o@nP|J?@^kt)Sbxh5TDGMoYAK z!aX+CY3x9Rx1x9ZY;EaC5Id7jD67!dMnM{3y?1vTJ*ez+Ct}~q(qt=n&yn)sRYALY zxQ({U8}^hwuA{X`B7`-onblgaar^8>-lsQN91rp2Af6AU)z5u`_vU}X^&9f1Mdl)) z5}pe_hRFpVS2CPMFberTjy`*QI@lc^jAR*97A`5Eoa6E${j;@)2lM(x z=EI+GzY==BB~IH@zw7-YLjf+(lNhH37i{!XhaMRY5XbnyuNEBt(^dQVk#Igf;$4Uv za6MVzaIXK6FM-#X0`iZ0$LT2!({)G2aXiI#weZI}Xc`VrwBo4}XRz`QZa#bb@N|xY zEKX=0zgzQ`d56ET;-kWE#m6?yt9l+@z}JcKTh{+b{`E$|608R%G1DhjKgcLwSyiwS z?|YV>g|Pwj=j%M8YUNe1p5tkY6N;a9sk$2Tw{koME+b`NeJ|C38TsiPPg9v?#pyq) z!r#u{2Rt=V3&U|MZq8GEnUQx0PAgngj1T?8`DduU?3Z^GPHR1VjLJ0bm*J<$s!y+% zo%oCSt%xT>_&NUsRp0N*%DA0|;FXdu;5ex2@lM(4Yph2`M! zN!Yq8^bC@B>V_1S4XK}CI^!b_ET#oHbWdPyMH))HSoCSUDW|VEEQ9V$qgzoQm12$u zRADQ=GOZsfewj+wC)1TM<^#w!2yTwHAw?aiXq{*a(|QSZLRG2r?{NsDPA8g8>c(VKi&`*0#A`@frM8(@;r5# zqkQFtIGg*Yk%|V+=6S|;s;)N>NT8Od^qC_0mU@n}Z>y$PizEM~O$ZS~bGoo1Ti~p% z>cACoF!x(4)OJWVasQ5}>Mn}^<9;jZAyMK8r%&s^EyM3|J*v5zSc#pWD-ig;Q;ZJ(Hef?IIT^G_(P1+&3hEzD$S0A}e%c^o{ z&FU?2t&m#cc6&d!Y2z<+gnt1SmEAk0KP~kEZj-u~yWh6vtrQ&L_siAotEO^qIHzz$ z6=Zzl$2I$WcIIS%=rKSf#%aN$>psD=PmSPlGk{tPUgZ09w?93J=T%)4dkK0>xu>gq z+OIslu!x>GK~KQAN>f55idPk*zkmDmMiB9^_^?&a_t78kc;>cXKma3Pg_ zR_m8}pMk$zg_L5dVpm)1iypZS^gbhD{T1|7lQ}cRoWl3B+~H~GGyn2+#w&R!R%hjC zo92-5&t<10OwXXmImD6*s}<{6;P7R|W#4qVeG5%RQI_PU)IlL3ING7>+RGz0()Al@ z>i$7(T}GpRJFO9=i4K}!m*>K$-bS~2I%RnJJ;kkzBx&zB=v!Uh4863Dt}P6$$_TCE za`i$r;P5436WzL#W^IZn+aEEN+nJJT`nXH?57J|&XqDsOd-DU%f*%gf8P&R0chxuO zg9iE{(myTF-x}9Cq{{pC&PUYoEfwhyaphz{-oXPF0`Kr^A4V2e=s2yR+o0a2 zi+qLKd%&F*doNLCf9G{0jGRBI8Rw2tE`E=aw0;5bG1=lL7YIPiO+Jka|9B-$ zN~FsXFT&O4_WAensxP!}p{NNiCqNk{E61ttsPoIlcZsaRWp zU@st&@pD{`9A!FlPWwB8y$J219uL9^emtL>jF+_%a1)_j@Iw`F`lqIUYqSkKe~R^B zXBa(hklg>Cwwc#e;$#uJ;rQ5B-ty4U{xtJLmAD60;>madWXog2J1w}0E#h=<)u)dQ zT8^8{&W9hZ@b^?5{mbBnyz0O7H6#%H3^(K6({+1baJM0EwI^zB=ffJrPp-Pn_Y7_v z9~sV;vv_RcySj#2gHpVN6e`BY`Lc1++`PKqFmy)oQa=)kYmO-xfBq+4UsM}9gpu$F zG6wbrE*;l1yS?UKG&qhSV@8uv=;L5PUHG#VUA%u04edveVF-;%>g2kCZK0wY)k9Z$ zpRF*o{fvZvMJ7G@uB~hQ&}0R*3$J-UKWTVtHd(NgBoB>ut(meMP>#~&4#94vhE}QM zmvoZ#Bx2Lzh^g=vQMVixJfKWV_mF*i$sRP(v<+slThSF3GYM^-K&3lP)|_t?+lz;f{S?RE9vkm(c2*e4!W%RI_B-QRb`NZo@` zWY}QRf4|2jPp2mA5B7h&@A?zEJ17$FNj!l2K}tV}BDX*I{yfN4;`K}DL%|eWPS*Ht zd*ph9*DrxN$itJ-Lst22+pE9M>zC9XYP5<#p92~e`2IXkef=KOKXr=V-2@_@uYA`J z()`Kex**~wP7m;1`nJVv|2}Ds7qr2SG^)b7*!~4P& zMaLFG9DH7*Zqzz=HG;ixMWdB{#{OeJy^3^^-tHZFze%(vneC^N7u&DvBf9BOmx!y4 z!$Js!?T^<^)jzRr@1ckS_An$I75IGK&8ls0x%INz!?;;Q;&#pkl~juM$;I7?+=Nk`5$UVdNH#&22l|J+-9l%me)tX>zfo6I~V$i zsZ5I|Y?C%^@alVs`K_qikCLKb!ac{Q9IjAo+*@39o6;k^)UISo9p?;Xv z;ahQkxAFRUL+D{zP)JKNn^6xL&T&7>Sg^$~q#9sK#>3LU3h};pel@1eGz>eX_B`P} zoa^~=8Vl&$V@w%p81c$)-@wotDB7$u7wK8u?;hjI4-BKcB9?p;F`-fF1n3-z@LF*g z_}vX-nnSnS225ue($uix_@YWpmT~jDhH>XTdSz)`5!dY`%|Y@MsnQJNu1xQQr_q!TmjjSGtWlj;gQ35YJj0HUnvw5BrN*JLV$PbQwtFgR~;X96l z2m;`wK*Y1jcz&p15w8d4dYzhqthqTXn+pK zP5iXPC@(W?h^Eog=v)^fg@hn3m)NM*{~*1aYS^-rZp@$s(E(3woC{gVG3`5PNS0xT z!0hwvTT-^DL3Bci)=Hc54H?I9pmaStjIwJ&0sYwjSX1j_!>_C9^3`;`BnRo;Jz-ZP z5E^Y-ddje8C(S9Q=NJ3M?YBi75+TjFNYlUP40|rKxNB3b0UW1B^c%d^ z@MRFI`)#ZA*Vyp>n%(_&t}uKynao*2)}x6gmc?D6Z94bAw8Stlixi$C*P$FTY(n6- zqCkCJfAa!^{~hx95qZ#9a=$kFT%@x9^$+_0`>mmC4Y~9?DSvjtExuC2_osXCU$YIG z6XZxf$xWzL%?DT?E0XvLO5KrSSL_TvHdp&sCdt@EU@yU5MV+%^ z|46}^N!lx$$@-OK3GP>uxsK~4t?$pd+Hy44OeYi2CjwWI>&cP6>;Kjs97BeOl8MkPaa2AH`HZX{lx0|!L9O~-FX}}Me!fw`S_ptRF*rxi^V|o!AXxd^FGJ= z_k30tI%}W|(K-Pq9aHoDdF}ntF6VZL+Z?9Hxc$cIS6%OX@7$`8_06$3r{YJz-^_R2 z{7EYrO+#oAg3;LGN2j=sa%lAeO+#>{S)5ZzmVtk!YcJ8Zk^9#y|7g{#!(5%0**5UH zWhF2CChzI(>Jn&M&+P>0AJ~n2JsMY^J2rpu{4d`bPX9+YaHY*dUT4Mk8FY+RtMfP5 z+%Ki&FqIJxFLy*~uA)!Q>snWlI{0gs>2)O>WQm1b;pk7Oj?O0cP=9!zK4M98#k2;0 zuIfuia`yqPyGw6le<06%{9omVhaB(RqP4f^ZS*?@a=yD#Z@}%VUyUz^sA?c@2;CQI zqA@k}A*SAEJWf9Rk6;sEieMbPa-MNecl)|C^vY|;_vS11iM1a&&-n3M_J4g# zP7TzQ!)T0F>>os@gYt|cOzq8+{MzP*j7me1k|njs9EN_?JmXZUedGC21HO((2x_Q{ zH`}3K^;L1^A>+#G_W$%B+#DZZ$(N$$NJ;U<2<_fKXw0o{|8jWOoOhj)@{xZrXTpT& zBqi-PUcT1;)jKv>V@U_-8Pq@6nd1>%*<+ONwwF!x>`|J9ehMftWJTG2cKy3O-9a~R zqU)g{;i}+$@m{buT4`;NtW2ew5kE%=h~wrKX_AY!6_^w0!q|pDN$SLLXQQ;Jm$vmR z8am*6GZi-$)h#*;77o=@7oQ@bzXD;@$K_4s2qv?~R-NUtQmeK8p=$U(=g+l}K zpv+;FEs=`GYwa$we0ty?X>JF+<5*Pxd+Ek>t@9uBTrthOd;wPy7v~$3>N{=M zopkLYI(?*AUSFdK38s!UjajVy@GCm(Q~GhfDL(JpH4s`fut%H9mT5jlQ+^Vw9L;Qef5jMRY=Lf$_8UfgU$%*{`oMgpiZv}v)nkQr z4UdO}_&;?GcnYb&D-2dGPSkFxp|v&iM%mK@*oP=_2Q>6oonETlT1)R*Xmg!IzK#D` z3<3kVkIrSWcAc7d_>%rl{cFlDDM43>xcKS5i`OOulK~$PkAm$#PTO`3S_t-@LHFBS z?R0y~KM!bi(uo*E_?cbj(o^?hrgro-di_3qx_E-k)A?=nnq)W{0bZ_Cv>~lXhi;^I z-W0?Bh;Fc!5oL|_3LLNX4I|OtlBA5#p=|@saxcT^HDrvoQ!2^WM{*PWfP793@jfSsn$zsrP>+L{I%QF;ii9hKD5!z^Qsg2^nvdo zbKEZeX*vsf7t$FKyadF@ST)YKZfAcor=jk*J!u_QTLDuXQC1ktGu#S;8sc9gI8W=) zj4w$Nv(K|5+_G(NNB&8xN@=bnHL^Z>MQ#J#Hl4ja;1{}jF`a{WU6n%|)`{$l+AV(Z zot|-Yb^=}dWWrO3XdJVz>U>6bx$Cr-mS3Z08b5S)??kvZ5{WDF@lCtb^uo~=E=Kg7 zu#^MmTr3F41f}@A)pY6Zb6S6gR-Zc&cE1u;{ff0eNq?>P}j|yQfQQv#QliA z`dty13s77HeOO@%3wKP!B2hBoq#ys)%*k>6qV!xLBMu**w1UNMZIe+KoT$@XT>vNQaDE1HV#nD!l)ALT6InFBaKx;m_ z{;vGX*ps!K4*SZ=PwRh|Q*2LO;O`3@e8XRTME+)P`ALB6?^HyQ2};70XgsaYk_Qbf zKU~H9RwR|e-;BRme(TAFJ@8wRLS=S{wGSoPRF-mK8;X>WLS^6zESz_vTsp?0Lo6O$h_Eq&_sWQH5ZXJtz0Ib=16zgKK6z^3vg~wgl$y)nd z5~QxzjAMDfDz|_5zAZ6cUTz$Tx?DWasEF5b`Z8lmZ(|s**M(imF_hOG zF+0#|@2xO;W{cKy{4f7%Bbg=k#v$U!@V+hMuPLefQ1nF;4WOLcy^8$P>NO=sd$AYn zs}r;o_6fF>`$ua^PCu;dc8NadOorne@h40U!GF54(mhAr?q_#5#1-+%NFBm&T~l)I zc%|+)zv;~($Qz=`#ZF(V^wF#?sXkcQxo%W%uZZ{3q)>dPqPuV*r8s_7N!|WRmx|Eo zH~fc=6#I1-`^78uNZpf4{yk9H;jo7`P16}3D?+~bWCT6|vCL?9w9=`BM0dBC?Uei` zM7;M>gQ15JbH3r~36FPB3;j<>0Jp&;>k zB$h0*_P_L$JN+OSdH(djc~}oQ>Ib2i$AMY=oYz6cY31|CF)(^h+ZG*)mybIlwwADR=J z%;~SZzW7pj3w1|7k>$K@5Oe@yjQ5a{IsdFA$?MVoqSPfuviNgiwzuK)oQFuNB895( zD|un%eeZg|H7w^k@1p@fj34%1aUJwE!*b4}7-<8d2BPZC?u8*^u) zsSquM%DKF$t8rEzFFZ62!8C-<*!YTHgFkt#KfXMDGKxUX(lcz4${=`d>I**IJrN&I zfC|DP;uVzH9c_>5vtI3<0Hp*Kq-dTubvP;d4I48i!oS0V%L0AN$C;x4&MtEbr5g64(J7e;$lGG6Kv=voAO8o39;-5!WAR7nk^l04>Ch@Na}DBwhv^Y$7@jY~ zpY(2iuFu?fl)V=QZ>i6Dr}?Fnv7OHg;cVIG7pk{6Wn^-HmaX4f=W|olIW*${k8dj; zfyG*PbW+vTvik^+Z~u2a2UI<_>@ESm<0o7STs>v|_>PdON8jDQ@j4|O3S2+_%1NrO zHR(nKhp!?3$mEc}@AoSGqV%hFH2M$moW&AjN|NN`I~(u?*Nzay$EJWTH`9Q z^4H@_v>a!deq-`X>!-=XI+t|i_7baCx8nN@xxXaz;y4Q>4$#!?72YbQ%29+pcZTz`1$&0$sXatfF30Jtl9uNwiHW6Yw9eyQ=l-U%su>t-%i}4 zdYXzVeY@JES#k%x@WuO~g(PA~lQ|xFRe&s7Q)kHSoP@6eBHT`dj>;BO5%PuKicdgH zH~nibOg`=Jx5J~YVzf)%aA6SWjy3(I65>{C><^QuB$Hjdxh~D5M{DX-)1?l=_wQNE zmuVr3YvGe1N^2_mYutpT2WiF*x|QWOm8$_QH^KC?kC42Hu3bY{f&%@+@GE4TY0f}l zGp{?spEH%K=)FkO&z{M`MF2T_3B{h z#(JTY=UcH148`feQqgYVEYG(>t`G#~^be)o`GS$>Te*Z|eEj4u9V!w2*v0y2a8DsZ zoZlcdRS17r`)FW+EB&5|p7%5*To9`G_dr|}q~>+JaeCSDns5%qz$i(={c7RwB>!+z zz(?Mc@7N&1%#(3|5{-OP5{{jr=c?!xUKGd2x0fxFaNti`dxzGs@$n~0p43jImxP@> z|H8je#P}0it3JIcY(TOVsZ|~!VK|jWRMW2s%aCkEYL(r0IFHIWuk06J73Og~W&J)V z1yuS?UfHj^C`{ttg}@2oPk5fuUX@WPL{$|PB8QVa zRA`ey(zlZJ437{$QSuSNKDOmKuMiwYC>S@6iG)J`&ZqmIIZqKBM(Gji3{hdi_`Py` zLfRaBJc#u1C*HtoFQR<^4bKgquRcF`*FbvpAf9^7&_b3E#k{i5v_l7L-Xk6!#G}zt zjrb}~6RN<;ZSIG;*N|^T9}PZ^)Z%}2ahr83_cHouP)~y5jW^#-LSO2%orf;+epTEr zKrq)Q?cBbak$wUFswk~w-;1#7AB)eBzPm5*I$jn>wU#OweSB>)F7mn#u79|m+3WLe zUdAO}XA6Czs7i*93HleInOC`A2F=r=&m;7gk7VAk(wVWr`3?GAHd(hh?m)@6;B0IC zRIjW@02em365-^}O;`7zENDE|C(HX8*-u9u{s_qWm-~;bo|fa9%Q}ajI%PHUdD%`P z-=qvR-NDa%xHYFUyMpU~myesD7anfM>D(UU{GQDx7arE|b%MWTJ#CuP{SJ5H`1oJk ze1y9C0ynPbnZC0ANu~Vb+JYXO&OL5E)M5Dt|AG%N4xsbDcEwJ4{?+`CcwQBHsRaku z$lrXMAHw}pE}wjyMe;X}`NOz>s*L|;-{#1(_UDa4(J!Er;{yK){Ud|(#sW+Molr9T zW${yt{K@UINxWZ1ksJkrm4C;|ofehN;CRaQEgvV!biYg4T;M5ER91dAb(ASbDE*%I zpK^W3`Nx`O#FQ@K_2k_C;qp1&)U93V3NDAdFGHCc>yc^;OV;tY1oXLLFR?hr1ZmUE zk}cRzKqu^WTsqD_N&3vQBpq@B=)_B53O?^-sr@5iKa8$I*j+4+YNZ>i@`S_X^xS<% z+y9>XRO7CngwjD|sYN}W^8=C+sOMDU!YJYVbNA#A{9%E^zDhtGSdyZq8YlJ>u11B{ zc8WmpZ4p9V?7M|UQ;lIggj+rl_GzKLLM7XBrC%lmap0-Oep=zLpZ&>fry6`84<%vv z$Wna`#tG;sJe_LuG@T6Bl;|UiT0g<)<0`hn z_ZYX*^*qji_rd{7!SG&lvEb*oD_AF?+z;e>&3GCrtF@_z2?x zKQY{l{LDCLy!gQzoQ1}-;@S{n*f(Nd;3iy7Y%)wE&L3(Vzg!&5>wbYdI0BAG{f)~u zi^Ea$3qO?Gdz}A&#^3gc5x~=J=%Z0Iq;>ocqz{gWQE9ASmDz8KpNKzsUpi7Ij?1F^ za%djI9V>q~lmGAHI9}h&cYx2UHzi*bqj>!i$_{~C90xm@&Qyz|Q1lBI6~)HbG46k9 zfV2$_UIM`M`d{Yd7-})Cd<9)HioZd>M`BUuP zNMAHNwr2cFe<&cb*?vK__-;EZo+=(X!>RmN_H}o~_MKUsA&A%q;3IyLwUM<#vj=&v z7xBgTSPaL_j=JA(2!Er#7cMI6i-`p4;rYtTh_U|X7q})UZXDx*JqKr z^T|TsPN22FCO^P?TBRT^BnuZ1rP4T1>7!A)a+Z0It`N$fP!+?+km34*i^7)GWXXIoQ_-sy)X^z;nyBAp64riA!UvN+iV@3#&k$Wfzumng z$(Qu#PCWDR?S=3!5bsSSjZgHuz9~uQL3+JU3{wN2R@vbDz-f?Dm3sf(lKJnGUT|Fz z2gcOOeYe!RtB-$M8rOw%a3F0_6oJxWXcahaJ=Eo0%kV84<$H$l<|33nGJ17a_3sbM zCg6L9w`olg`(7faJE<=p&l`7xUI(P2P8e5@c?b3X>MyUzAA`DCd;$XTJp^yLe!Hr# z8d?zXCZ5Ke3#Q+4_2vH*jO2KVdj!{j>!n2f!KH`s9YQ6p%PS~2eXM>%{ozrZ4hmMz z=>htgAFw_b{PbVkX|L}$`p8!xVhV6ViE(tOb8Q`cB>F%8tO6Oh1%gBAs3TLk|A_wu z?kN8f+szIOdLNn1{YRV^R66JX#$kZnk$HT4$ZZS%aEH#94u6mFp>Mf90Y4ruhgKU7 zCvZC!C#d`h%fqT1S`9h8jK`&M+%0(2pt65afbV7~aY(iv>-%0&>30{b=ljNR(CWgU zQ1uvGuoZZXknewSHcRFAAU_>JV1#@Xzlm)=*0Vw7w=91z@1p_EauXW#WhyUSelCwk z@e}0hk5~05%sXoR&V#Z)Rug5ms%vGX2KslT?~j zW#>3TcCx<=n<4pxA?`e^7-FN9w45e_!sJAe0LhFf>xO(7cM9_Cd@rJ_ zCsM1>idYi*W&BE>LGR%^iuo4Ub=L1S&6ZOdh1ciV_q8DBFg0;6uu*aH55;1e3R?BV zu`SD2THkAqJTX~x7(!M)S5IL6mlvcxfvV@oUrZ4@y>d_O>wj0V6D;@+F!HKVaq@>l z#I93A>$^ro#WpmB)y}CF6Yw42*|LY9=-oTQDKj*nUaZFV@$iuc;3@ppZsLdO{`TKH zJ@A&iy`|883{R(-%x+?6oXv|pWKUDj!X@+YViGsc_HFVjTL1t6 literal 0 HcmV?d00001 diff --git a/sample-data/multi-segment/041s/041s01.hea b/sample-data/multi-segment/041s/041s01.hea new file mode 100644 index 00000000..d5d52779 --- /dev/null +++ b/sample-data/multi-segment/041s/041s01.hea @@ -0,0 +1,9 @@ +041s01 7 125 1000 8:26:04 26/10/1994 +041s01.dat 212x4 2000 12 0 168 -2716 0 III +041s01.dat 212x4 2000 12 0 2 -25019 0 I +041s01.dat 212x4 2000 12 0 155 -12467 0 V +041s01.dat 212 20(-1600)/mmHg 12 0 -242 -18875 0 ABP +041s01.dat 212 80(-1600)/mmHg 12 0 706 -5338 0 PAP +041s01.dat 212 2000 12 0 -841 30145 0 PLETH +041s01.dat 212 2000 12 0 401 3712 0 RESP +#Produced by xform from record mimicdb/041/04100001, beginning at s74000 diff --git a/sample-data/multi-segment/041s/041s02.dat b/sample-data/multi-segment/041s/041s02.dat new file mode 100644 index 0000000000000000000000000000000000000000..0df680dba230c32ed9eb1672e5157600f7119a3e GIT binary patch literal 24000 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 Bl}7*o literal 0 HcmV?d00001 diff --git a/sample-data/multi-segment/041s/041s02.hea b/sample-data/multi-segment/041s/041s02.hea new file mode 100644 index 00000000..46d856bb --- /dev/null +++ b/sample-data/multi-segment/041s/041s02.hea @@ -0,0 +1,9 @@ +041s02 7 125 1000 8:26:12 26/10/1994 +041s02.dat 212x4 2000 12 0 -103 -862 0 III +041s02.dat 212x4 2000 12 0 -64 14967 0 I +041s02.dat 212x4 2000 12 0 89 13162 0 V +041s02.dat 212 20(-1600)/mmHg 12 0 -715 -21117 0 ABP +041s02.dat 212 80(-1600)/mmHg 12 0 -583 -31770 0 PAP +041s02.dat 212 2000 12 0 -840 -31041 0 PLETH +041s02.dat 212 2000 12 0 -861 -31272 0 RESP +#Produced by xform from record mimicdb/041/04100002, beginning at 0:0 diff --git a/tests/target-output/record-multi-fixed-d.gz b/tests/target-output/record-multi-fixed-d.gz new file mode 100644 index 0000000000000000000000000000000000000000..5b71223cb3427ab7cf7f9495613f49e1c3b7bc08 GIT binary patch literal 26883 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 DD33UW literal 0 HcmV?d00001 diff --git a/tests/test_record.py b/tests/test_record.py index d0f4da1d..ce7674e4 100644 --- a/tests/test_record.py +++ b/tests/test_record.py @@ -746,6 +746,41 @@ def test_multi_fixed_c(self): np.testing.assert_equal(sig_round, sig_target) assert record.__eq__(record_named) + def test_multi_fixed_d(self): + """ + Multi-segment, fixed layout, multi-frequency, selected channels + + Target file created with: + rdsamp -r sample-data/multi-segment/041s/ -s 3 2 1 -H | + cut -f 2- | sed s/-32768/-2048/ | + gzip -9 -n > tests/target-output/record-multi-fixed-d.gz + """ + record = wfdb.rdrecord( + "sample-data/multi-segment/041s/041s", + channels=[3, 2, 1], + physical=False, + smooth_frames=False, + ) + + # Convert expanded to uniform array (high-resolution) + sig = np.zeros((record.sig_len * 4, record.n_sig), dtype=int) + for i, s in enumerate(record.e_d_signal): + sig[:, i] = np.repeat(s, len(sig[:, i]) // len(s)) + + sig_target = np.genfromtxt( + "tests/target-output/record-multi-fixed-d.gz" + ) + + record_named = wfdb.rdrecord( + "sample-data/multi-segment/041s/041s", + channel_names=["ABP", "V", "I"], + physical=False, + smooth_frames=False, + ) + + np.testing.assert_array_equal(sig, sig_target) + assert record.__eq__(record_named) + def test_multi_variable_a(self): """ Multi-segment, variable layout, selected duration, samples read From f1f805b7454889d38550669a1caf9d1126d91e0f Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 12 Oct 2021 17:16:57 -0400 Subject: [PATCH 7/9] Test reading variable-layout signals in expanded format. Modify the existing test case test_multi_variable_c to check that we can read a single-frequency variable-layout record using smooth_frames=False (which should retrieve the same data as smooth_frames=True, but represented as a list of arrays rather than a single array.) --- tests/test_record.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/test_record.py b/tests/test_record.py index ce7674e4..7d13bc4a 100644 --- a/tests/test_record.py +++ b/tests/test_record.py @@ -823,7 +823,7 @@ def test_multi_variable_b(self): def test_multi_variable_c(self): """ - Multi-segment, variable layout, entire signal, physical + Multi-segment, variable layout, entire signal, physical, expanded The reference signal creation cannot be made with rdsamp directly because the WFDB c package (10.5.24) applies the single @@ -846,9 +846,14 @@ def test_multi_variable_c(self): """ record = wfdb.rdrecord( - "sample-data/multi-segment/s25047/s25047-2704-05-04-10-44" + "sample-data/multi-segment/s25047/s25047-2704-05-04-10-44", + smooth_frames=False, ) - sig_round = np.round(record.p_signal, decimals=8) + + # convert expanded to uniform array and round to 8 digits + sig_round = np.zeros((record.sig_len, record.n_sig)) + for i in range(record.n_sig): + sig_round[:, i] = np.round(record.e_p_signal[i], decimals=8) sig_target_a = np.full((25740, 3), np.nan) sig_target_b = np.concatenate( From f2044a995f418fd05ac2efbc66bd9346a526e3f6 Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 3 May 2022 16:45:15 -0400 Subject: [PATCH 8/9] multi_to_single: reformat error message as f-string. --- wfdb/io/record.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/wfdb/io/record.py b/wfdb/io/record.py index e67acc24..9a4c477d 100644 --- a/wfdb/io/record.py +++ b/wfdb/io/record.py @@ -1358,16 +1358,13 @@ def multi_to_single(self, physical, return_res=64, expanded=False): # mismatch case elif reference_fields[field][ch] != item_ch: if field == "samps_per_frame": + expected = reference_fields[field][ch] raise ValueError( - "Incorrect samples per frame (%s != %s) " - "for signal %s in segment %s of %s" - % ( - item_ch, - reference_fields[field][ch], - signal_names[ch], - seg.record_name, - self.record_name, - ) + f"Incorrect samples per frame " + f"({item_ch} != {expected}) " + f"for signal {signal_names[ch]} " + f"in segment {seg.record_name} " + f"of {self.record_name}" ) elif physical: mismatched_fields.append(field) From 4f06a062f8527a2ae2149f40f59a7a55137e9392 Mon Sep 17 00:00:00 2001 From: Benjamin Moody Date: Tue, 3 May 2022 16:46:10 -0400 Subject: [PATCH 9/9] test_multi_fixed_d: add comments and use assertEqual. --- tests/test_record.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_record.py b/tests/test_record.py index 7d13bc4a..c0b910fa 100644 --- a/tests/test_record.py +++ b/tests/test_record.py @@ -778,8 +778,10 @@ def test_multi_fixed_d(self): smooth_frames=False, ) + # Sample values should match the output of rdsamp -H np.testing.assert_array_equal(sig, sig_target) - assert record.__eq__(record_named) + # channel_names=[...] should give the same result as channels=[...] + self.assertEqual(record, record_named) def test_multi_variable_a(self): """