0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
1 % HETERODYNE heterodynes time-series.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
3 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
4 % DESCRIPTION: HETERODYNE heterodynes time-series.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
5 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
6 % The input signal is mixed down at the specified frequency. The mixed
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
7 % signal is then (optionally) low-pass filtered and (optionally) downsampled
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
8 % to have the specified bandwidth.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
9 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
10 % CALL: b = heterodyne(a,pl)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
11 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
12 % INPUTS: pl - a parameter list
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
13 % a - input analysis object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
14 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
15 % OUTPUTS: b - output analysis object containing the filtered data.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
16 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
17 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'heterodyne')">Parameters Description</a>
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
18 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
19 % VERSION: $Id: heterodyne.m,v 1.22 2011/04/08 08:56:16 hewitson Exp $
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
20 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
22
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
23 function varargout = heterodyne(varargin)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
24
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
25 % Check if this is a call for parameters
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
26 if utils.helper.isinfocall(varargin{:})
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
27 varargout{1} = getInfo(varargin{3});
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
28 return
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
29 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
30
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
31 import utils.const.*
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
32 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
33
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
34 % Collect input variable names
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
35 in_names = cell(size(varargin));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
36 for ii = 1:nargin,in_names{ii} = inputname(ii);end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
37
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
38 % Collect all AOs and plists
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
39 [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
40 [pl, pl_invars] = utils.helper.collect_objects(varargin(:), 'plist', in_names);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
41
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
42 % Make copies or handles to inputs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
43 bs = copy(as, nargout);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
44
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
45 % Combine plists
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
46 pl = parse(pl, getDefaultPlist());
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
47
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
48
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
49 % Get parameters
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
50 t0 = find(pl, 't0');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
51 f0 = find(pl, 'f0');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
52 if isempty(f0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
53 error('### Please specify the heterodyne frequency with the paramter ''f0''');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
54 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
55 mix = find(pl, 'quad');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
56
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
57 for jj = 1:numel(bs)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
58 if isa(bs(jj).data, 'tsdata')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
59
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
60 % store input history
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
61 inhist = bs(jj).hist;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
62
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
63 % check bandwidth
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
64 bw = find(pl, 'bw');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
65 if isempty(bw)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
66 bw = bs(jj).data.fs;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
67 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
68 if bw > bs(jj).data.fs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
69 error('### The output bandwidth can not exceed the input bandwidth');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
70 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
71
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
72 % mix at f0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
73 switch lower(mix)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
74 case 'cos'
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
75 bs(jj).data.setY(bs(jj).data.getY .* 2.0 .* cos(2*pi * f0 .* (bs(jj).data.getX - t0)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
76 case 'sin'
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
77 bs(jj).data.setY(bs(jj).data.getY .* 2.0 .* sin(2*pi * f0 .* (bs(jj).data.getX - t0)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
78 otherwise
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
79 error('### Unknown quadrature specified');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
80 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
81
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
82
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
83 % user-input filter for low pass
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
84 filt = find(pl, 'filter');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
85
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
86 % lowpass filter at bw/w
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
87 if ~isempty(filt) || utils.prog.yes2true(find(pl, 'lp'))
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
88 if isempty(filt)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
89 % standard filter for low-pass
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
90 filt = miir(plist('type', 'lowpass', 'order', 4, 'fc', 0.4*bw, 'fs', bs(jj).data.fs));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
91 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
92 bs.filtfilt(filt);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
93 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
94
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
95 % downsample
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
96 if utils.prog.yes2true(find(pl, 'ds'))
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
97 factor = ceil(bs(jj).data.fs / bw);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
98 bs.downsample(plist('factor', factor));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
99 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
100
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
101 % set name and history
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
102 bs(jj).name = sprintf('heterodyne(%s, %s@%.01f Hz)', ao_invars{jj}, mix, f0);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
103 bs(jj).addHistory(getInfo('None'), pl, ao_invars(jj), inhist);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
104 % clear errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
105 bs(jj).clearErrors;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
106
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
107 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
108 error('### heterodyne only works on time-series AOs currently.');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
109 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
110 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
111
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
112 % Set output
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
113 if nargout == numel(bs)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
114 % List of outputs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
115 for ii = 1:numel(bs)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
116 varargout{ii} = bs(ii);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
117 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
118 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
119 % Single output
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
120 varargout{1} = bs;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
121 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
122 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
123
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
124 %--------------------------------------------------------------------------
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
125 % Get Info Object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
126 %--------------------------------------------------------------------------
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
127 function ii = getInfo(varargin)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
128 if nargin == 1 && strcmpi(varargin{1}, 'None')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
129 sets = {};
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
130 pls = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
131 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
132 sets = {'Default'};
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
133 pls = getDefaultPlist;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
134 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
135 % Build info object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
136 ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: heterodyne.m,v 1.22 2011/04/08 08:56:16 hewitson Exp $', sets, pls);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
137 ii.setModifier(false);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
138 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
139
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
140 %--------------------------------------------------------------------------
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
141 % Get Default Plist
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
142 %--------------------------------------------------------------------------
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
143 function plout = getDefaultPlist()
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
144 persistent pl;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
145 if exist('pl', 'var')==0 || isempty(pl)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
146 pl = buildplist();
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
147 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
148 plout = pl;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
149 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
150
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
151 function pl = buildplist()
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
152
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
153 pl = plist();
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
154
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
155 % f0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
156 p = param({'f0', 'The heterodyne frequency in Hz.'}, paramValue.EMPTY_DOUBLE);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
157 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
158
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
159 % t0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
160 p = param({'t0', 'Modulation start time offset in s.'}, paramValue.DOUBLE_VALUE(0));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
161 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
162
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
163 % quad
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
164 p = param({'quad', 'The quadrature to output. ''sin'' or ''cos''.'},{2, {'sin', 'cos'}, paramValue.SINGLE});
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
165 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
166
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
167 % bw
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
168 p = param({'bw', 'The bandwidth at the output in Hz.'}, paramValue.EMPTY_DOUBLE);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
169 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
170
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
171 % lp
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
172 p = param({'lp', 'Low pass filter the output data at ''bw''.'}, paramValue.YES_NO);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
173 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
174
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
175 % filter
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
176 p = param({'filter', ['Filter to be used to low pass the output data.<br>' ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
177 'If this parameter is set, the low pass is applied regardless to the value of the ''lp'' parameter']}, paramValue.EMPTY_DOUBLE);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
178 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
179
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
180 % ds
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
181 p = param({'ds','Downsample the output data.'}, paramValue.YES_NO);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
182 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
183 end
|