pvlib 0.10.5__py3-none-any.whl → 0.11.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvlib/__init__.py +1 -0
- pvlib/albedo.py +168 -0
- pvlib/data/ASTMG173.csv +2004 -0
- pvlib/iam.py +28 -28
- pvlib/iotools/__init__.py +0 -1
- pvlib/iotools/midc.py +15 -10
- pvlib/iotools/psm3.py +10 -25
- pvlib/iotools/srml.py +0 -61
- pvlib/irradiance.py +133 -95
- pvlib/location.py +13 -5
- pvlib/modelchain.py +2 -165
- pvlib/pvsystem.py +23 -63
- pvlib/shading.py +350 -0
- pvlib/spectrum/__init__.py +5 -0
- pvlib/spectrum/mismatch.py +572 -43
- pvlib/spectrum/spectrl2.py +8 -8
- pvlib/tests/iotools/test_psm3.py +0 -18
- pvlib/tests/iotools/test_srml.py +1 -43
- pvlib/tests/test_albedo.py +84 -0
- pvlib/tests/test_inverter.py +2 -2
- pvlib/tests/test_irradiance.py +35 -2
- pvlib/tests/test_location.py +26 -18
- pvlib/tests/test_modelchain.py +0 -57
- pvlib/tests/test_pvsystem.py +11 -39
- pvlib/tests/test_shading.py +167 -1
- pvlib/tests/test_singlediode.py +0 -19
- pvlib/tests/test_spectrum.py +283 -22
- pvlib/tests/test_temperature.py +7 -7
- pvlib/tests/test_tools.py +24 -0
- pvlib/tests/test_transformer.py +60 -0
- pvlib/tools.py +27 -0
- pvlib/transformer.py +117 -0
- {pvlib-0.10.5.dist-info → pvlib-0.11.0.dist-info}/METADATA +1 -1
- {pvlib-0.10.5.dist-info → pvlib-0.11.0.dist-info}/RECORD +38 -34
- {pvlib-0.10.5.dist-info → pvlib-0.11.0.dist-info}/WHEEL +1 -1
- pvlib/data/astm_g173_am15g.csv +0 -2003
- {pvlib-0.10.5.dist-info → pvlib-0.11.0.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.10.5.dist-info → pvlib-0.11.0.dist-info}/LICENSE +0 -0
- {pvlib-0.10.5.dist-info → pvlib-0.11.0.dist-info}/top_level.txt +0 -0
pvlib/shading.py
CHANGED
|
@@ -342,3 +342,353 @@ def projected_solar_zenith_angle(solar_zenith, solar_azimuth,
|
|
|
342
342
|
# Eq. (5); angle between sun's beam and surface
|
|
343
343
|
theta_T = np.degrees(np.arctan2(sx_prime, sz_prime))
|
|
344
344
|
return theta_T
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def shaded_fraction1d(
|
|
348
|
+
solar_zenith,
|
|
349
|
+
solar_azimuth,
|
|
350
|
+
axis_azimuth,
|
|
351
|
+
shaded_row_rotation,
|
|
352
|
+
*,
|
|
353
|
+
collector_width,
|
|
354
|
+
pitch,
|
|
355
|
+
axis_tilt=0,
|
|
356
|
+
surface_to_axis_offset=0,
|
|
357
|
+
cross_axis_slope=0,
|
|
358
|
+
shading_row_rotation=None,
|
|
359
|
+
):
|
|
360
|
+
r"""
|
|
361
|
+
Shaded fraction in the vertical dimension of tilted rows, or perpendicular
|
|
362
|
+
to the axis of horizontal rows.
|
|
363
|
+
|
|
364
|
+
If ``shading_row_rotation`` isn't provided, it is assumed that
|
|
365
|
+
both the shaded row and the shading row (the one blocking the
|
|
366
|
+
direct beam) have the same rotation and azimuth values.
|
|
367
|
+
|
|
368
|
+
.. warning::
|
|
369
|
+
The function assumes that the roles of the shaded and shading rows
|
|
370
|
+
remain the same during the day. In the case where the shading and
|
|
371
|
+
shaded rows change throughout the day, e.g. a N-S single-axis tracker,
|
|
372
|
+
the inputs must be switched depending on the sign of the projected
|
|
373
|
+
solar zenith angle. See the Examples section below.
|
|
374
|
+
|
|
375
|
+
.. versionadded:: 0.11.0
|
|
376
|
+
|
|
377
|
+
Parameters
|
|
378
|
+
----------
|
|
379
|
+
solar_zenith : numeric
|
|
380
|
+
Solar zenith angle, in degrees.
|
|
381
|
+
solar_azimuth : numeric
|
|
382
|
+
Solar azimuth angle, in degrees.
|
|
383
|
+
axis_azimuth : numeric
|
|
384
|
+
Axis azimuth of the rotation axis of a tracker, in degrees.
|
|
385
|
+
Fixed-tilt arrays can be considered as a particular case of a tracker.
|
|
386
|
+
North=0º, South=180º, East=90º, West=270º.
|
|
387
|
+
shaded_row_rotation : numeric
|
|
388
|
+
Right-handed rotation of the row receiving the shade, with respect
|
|
389
|
+
to ``axis_azimuth``. In degrees :math:`^{\circ}`.
|
|
390
|
+
collector_width : numeric
|
|
391
|
+
Vertical length of a tilted row. The returned ``shaded_fraction``
|
|
392
|
+
is the ratio of the shadow over this value.
|
|
393
|
+
pitch : numeric
|
|
394
|
+
Axis-to-axis horizontal spacing of the row.
|
|
395
|
+
axis_tilt : numeric, default 0
|
|
396
|
+
Tilt of the rows axis from horizontal. In degrees :math:`^{\circ}`.
|
|
397
|
+
surface_to_axis_offset : numeric, default 0
|
|
398
|
+
Distance between the rotating axis and the collector surface.
|
|
399
|
+
May be used to account for a torque tube offset.
|
|
400
|
+
cross_axis_slope : numeric, default 0
|
|
401
|
+
Angle of the plane containing the rows' axes from
|
|
402
|
+
horizontal. Right-handed rotation with respect to the rows axes.
|
|
403
|
+
In degrees :math:`^{\circ}`.
|
|
404
|
+
shading_row_rotation : numeric, optional
|
|
405
|
+
Right-handed rotation of the row casting the shadow, with respect
|
|
406
|
+
to the row axis. In degrees :math:`^{\circ}`.
|
|
407
|
+
|
|
408
|
+
Returns
|
|
409
|
+
-------
|
|
410
|
+
shaded_fraction : numeric
|
|
411
|
+
The fraction of the collector width shaded by an adjacent row. A
|
|
412
|
+
value of 1 is completely shaded and 0 is no shade.
|
|
413
|
+
|
|
414
|
+
Notes
|
|
415
|
+
-----
|
|
416
|
+
All length parameters must have the same units.
|
|
417
|
+
|
|
418
|
+
Parameters are defined as follow:
|
|
419
|
+
|
|
420
|
+
.. figure:: ../../_images/Anderson_Jensen_2024_Fig3.png
|
|
421
|
+
:alt: Diagram showing the two rows and the parameters of the model.
|
|
422
|
+
|
|
423
|
+
Figure 3 of [1]_. See correspondence between this nomenclature and the
|
|
424
|
+
function parameters in the table below.
|
|
425
|
+
|
|
426
|
+
+------------------+----------------------------+---------------------+
|
|
427
|
+
| Symbol | Parameter | Units |
|
|
428
|
+
+==================+============================+=====================+
|
|
429
|
+
| :math:`\theta_1` | ``shading_row_rotation`` | |
|
|
430
|
+
+------------------+----------------------------+ |
|
|
431
|
+
| :math:`\theta_2` | ``shaded_row_rotation`` | Degrees |
|
|
432
|
+
+------------------+----------------------------+ :math:`^{\circ}` |
|
|
433
|
+
| :math:`\beta_c` | ``cross_axis_slope`` | |
|
|
434
|
+
+------------------+----------------------------+---------------------+
|
|
435
|
+
| :math:`p` | ``pitch`` | Any consistent |
|
|
436
|
+
+------------------+----------------------------+ length unit across |
|
|
437
|
+
| :math:`\ell` | ``collector_width`` | all these |
|
|
438
|
+
+------------------+----------------------------+ parameters, e.g. |
|
|
439
|
+
| :math:`z_0` | ``surface_to_axis_offset`` | :math:`m`. |
|
|
440
|
+
+------------------+----------------------------+---------------------+
|
|
441
|
+
| :math:`f_s` | Return value | Dimensionless |
|
|
442
|
+
+------------------+----------------------------+---------------------+
|
|
443
|
+
|
|
444
|
+
Examples
|
|
445
|
+
--------
|
|
446
|
+
|
|
447
|
+
**Fixed-tilt south-facing array on flat terrain**
|
|
448
|
+
|
|
449
|
+
Tilted row with a pitch of 3 m, a collector width of
|
|
450
|
+
2 m, and row rotations of 30°. In the morning.
|
|
451
|
+
|
|
452
|
+
>>> shaded_fraction1d(solar_zenith=80, solar_azimuth=104.5,
|
|
453
|
+
... axis_azimuth=90, shaded_row_rotation=30, shading_row_rotation=30,
|
|
454
|
+
... collector_width=2, pitch=3, axis_tilt=0,
|
|
455
|
+
... surface_to_axis_offset=0.05, cross_axis_slope=0)
|
|
456
|
+
0.6827437712114521
|
|
457
|
+
|
|
458
|
+
**Fixed-tilt north-facing array on sloped terrain**
|
|
459
|
+
|
|
460
|
+
Tilted row with a pitch of 4 m, a collector width of
|
|
461
|
+
2.5 m, and row rotations of 50° for the shaded
|
|
462
|
+
row and 30° for the shading row. The rows are on a
|
|
463
|
+
10° slope, where their axis is on the most inclined
|
|
464
|
+
direction (zero cross-axis slope). Shaded in the morning.
|
|
465
|
+
|
|
466
|
+
>>> shaded_fraction1d(solar_zenith=65, solar_azimuth=75.5,
|
|
467
|
+
... axis_azimuth=270, shaded_row_rotation=50, shading_row_rotation=30,
|
|
468
|
+
... collector_width=2.5, pitch=4, axis_tilt=10,
|
|
469
|
+
... surface_to_axis_offset=0.05, cross_axis_slope=0)
|
|
470
|
+
0.6975923460352351
|
|
471
|
+
|
|
472
|
+
**N-S single-axis tracker on sloped terrain**
|
|
473
|
+
|
|
474
|
+
Horizontal trackers with a pitch of 3 m, a collector width of
|
|
475
|
+
1.4 m, and tracker rotations of 30° pointing east,
|
|
476
|
+
in the morning. Terrain slope is 7° west-east (east-most
|
|
477
|
+
tracker is higher than the west-most tracker).
|
|
478
|
+
|
|
479
|
+
>>> shaded_fraction1d(solar_zenith=50, solar_azimuth=90, axis_azimuth=180,
|
|
480
|
+
... shaded_row_rotation=-30, collector_width=1.4, pitch=3, axis_tilt=0,
|
|
481
|
+
... surface_to_axis_offset=0.10, cross_axis_slope=7)
|
|
482
|
+
0.5828961460616938
|
|
483
|
+
|
|
484
|
+
Note the previous example only is valid for the shaded fraction of the
|
|
485
|
+
west-most tracker in the morning, and assuming it is the
|
|
486
|
+
shaded tracker during all the day is incorrect.
|
|
487
|
+
During the afternoon, it is the one casting the shadow onto the
|
|
488
|
+
east-most tracker.
|
|
489
|
+
|
|
490
|
+
To calculate the shaded fraction for the east-most
|
|
491
|
+
tracker, you must input the corresponding ``shaded_row_rotation``
|
|
492
|
+
in the afternoon.
|
|
493
|
+
|
|
494
|
+
>>> shaded_fraction1d(solar_zenith=50, solar_azimuth=270, axis_azimuth=180,
|
|
495
|
+
... shaded_row_rotation=30, collector_width=1.4, pitch=3, axis_tilt=0,
|
|
496
|
+
... surface_to_axis_offset=0.10, cross_axis_slope=7)
|
|
497
|
+
0.4399034444363955
|
|
498
|
+
|
|
499
|
+
You must switch the input/output depending on the
|
|
500
|
+
sign of the projected solar zenith angle. See
|
|
501
|
+
:py:func:`~pvlib.shading.projected_solar_zenith_angle` and the example
|
|
502
|
+
:ref:`sphx_glr_gallery_shading_plot_shaded_fraction1d_ns_hsat_example.py`
|
|
503
|
+
|
|
504
|
+
See also
|
|
505
|
+
--------
|
|
506
|
+
pvlib.shading.projected_solar_zenith_angle
|
|
507
|
+
|
|
508
|
+
References
|
|
509
|
+
----------
|
|
510
|
+
.. [1] Kevin S. Anderson, Adam R. Jensen; Shaded fraction and backtracking
|
|
511
|
+
in single-axis trackers on rolling terrain. J. Renewable Sustainable
|
|
512
|
+
Energy 1 March 2024; 16 (2): 023504. :doi:`10.1063/5.0202220`
|
|
513
|
+
"""
|
|
514
|
+
# For nomenclature you may refer to [1].
|
|
515
|
+
|
|
516
|
+
# rotation of row casting the shadow defaults to shaded row's one
|
|
517
|
+
if shading_row_rotation is None:
|
|
518
|
+
shading_row_rotation = shaded_row_rotation
|
|
519
|
+
|
|
520
|
+
# projected solar zenith angle
|
|
521
|
+
projected_solar_zenith = projected_solar_zenith_angle(
|
|
522
|
+
solar_zenith,
|
|
523
|
+
solar_azimuth,
|
|
524
|
+
axis_tilt,
|
|
525
|
+
axis_azimuth,
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
# calculate repeated elements
|
|
529
|
+
thetas_1_S_diff = shading_row_rotation - projected_solar_zenith
|
|
530
|
+
thetas_2_S_diff = shaded_row_rotation - projected_solar_zenith
|
|
531
|
+
thetaS_rotation_diff = projected_solar_zenith - cross_axis_slope
|
|
532
|
+
|
|
533
|
+
cos_theta_2_S_diff_abs = np.abs(cosd(thetas_2_S_diff))
|
|
534
|
+
|
|
535
|
+
# Eq. (12) of [1]
|
|
536
|
+
t_asterisk = (
|
|
537
|
+
0.5
|
|
538
|
+
+ np.abs(cosd(thetas_1_S_diff)) / cos_theta_2_S_diff_abs / 2
|
|
539
|
+
+ (
|
|
540
|
+
np.sign(projected_solar_zenith)
|
|
541
|
+
* surface_to_axis_offset
|
|
542
|
+
/ collector_width
|
|
543
|
+
/ cos_theta_2_S_diff_abs
|
|
544
|
+
* (sind(thetas_2_S_diff) - sind(thetas_1_S_diff))
|
|
545
|
+
)
|
|
546
|
+
- (
|
|
547
|
+
pitch
|
|
548
|
+
/ collector_width
|
|
549
|
+
* cosd(thetaS_rotation_diff)
|
|
550
|
+
/ cos_theta_2_S_diff_abs
|
|
551
|
+
/ cosd(cross_axis_slope)
|
|
552
|
+
)
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
return np.clip(t_asterisk, 0, 1)
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def direct_martinez(
|
|
559
|
+
poa_global,
|
|
560
|
+
poa_direct,
|
|
561
|
+
shaded_fraction,
|
|
562
|
+
shaded_blocks,
|
|
563
|
+
total_blocks,
|
|
564
|
+
):
|
|
565
|
+
r"""
|
|
566
|
+
A shading loss power factor for non-monolithic silicon
|
|
567
|
+
modules and arrays with an arbitrary number of bypass diodes.
|
|
568
|
+
|
|
569
|
+
This experimental model reduces the direct and circumsolar
|
|
570
|
+
irradiance reaching the module's cells based on the number of *blocks*
|
|
571
|
+
affected by the shadow.
|
|
572
|
+
More on blocks in the *Notes* section and in [1]_.
|
|
573
|
+
|
|
574
|
+
.. versionadded:: 0.11.0
|
|
575
|
+
|
|
576
|
+
Parameters
|
|
577
|
+
----------
|
|
578
|
+
poa_global : numeric
|
|
579
|
+
Plane of array global irradiance. [W/m²].
|
|
580
|
+
poa_direct : numeric
|
|
581
|
+
Plane of array direct and circumsolar irradiance. [W/m²].
|
|
582
|
+
shaded_fraction : numeric
|
|
583
|
+
Fraction of module surface area that is shaded. [Unitless].
|
|
584
|
+
shaded_blocks : numeric
|
|
585
|
+
Number of blocks affected by the shadow. [Unitless].
|
|
586
|
+
If a floating point number is provided, it will be rounded up.
|
|
587
|
+
total_blocks : int
|
|
588
|
+
Number of total blocks. Unitless.
|
|
589
|
+
|
|
590
|
+
Returns
|
|
591
|
+
-------
|
|
592
|
+
shading_losses : numeric
|
|
593
|
+
Fraction of DC power lost due to shading. [Unitless]
|
|
594
|
+
|
|
595
|
+
Notes
|
|
596
|
+
-----
|
|
597
|
+
The implemented equations are (6) and (8) from [1]_:
|
|
598
|
+
|
|
599
|
+
.. math::
|
|
600
|
+
|
|
601
|
+
(1 - F_{ES}) = (1 - F_{GS}) \left(1 - \frac{N_{SB}}{N_{TB} + 1}\right)
|
|
602
|
+
\quad \text{(6)}
|
|
603
|
+
|
|
604
|
+
\left(1 - \frac{P_{S}}{P_{NS}}\right) = \left(1 -
|
|
605
|
+
\frac{\left[(B + D^{CIR})(1 - F_{ES}) + D^{ISO} + R\right]}{G}\right)
|
|
606
|
+
\quad \text{(8)}
|
|
607
|
+
|
|
608
|
+
In (6), :math:`(1 - F_{ES})` is the correction factor to be multiplied by
|
|
609
|
+
the direct and circumsolar irradiance, :math:`F_{GS}` is the shaded
|
|
610
|
+
fraction of the collector, :math:`N_{SB}` is the number of shaded blocks
|
|
611
|
+
and :math:`N_{TB}` is the number of total blocks.
|
|
612
|
+
|
|
613
|
+
In (8), :math:`\frac{P_{S}}{P_{NS}}` is the fraction of DC power lost due
|
|
614
|
+
to shading, :math:`P_{S}` is the power output of the shaded module,
|
|
615
|
+
:math:`P_{NS}` is the power output of the non-shaded module,
|
|
616
|
+
:math:`B + D^{CIR}` is the beam and circumsolar irradiance,
|
|
617
|
+
:math:`D^{ISO} + R` is the sum of diffuse and albedo irradiances and
|
|
618
|
+
:math:`G` is the global irradiance.
|
|
619
|
+
|
|
620
|
+
**Blocks terminology:**
|
|
621
|
+
|
|
622
|
+
A *block* is defined in [1]_ as a group of solar cells protected by a
|
|
623
|
+
bypass diode. Also, a *block* is shaded when at least one of its
|
|
624
|
+
cells is partially shaded.
|
|
625
|
+
|
|
626
|
+
The total number of blocks and their layout depend on the module(s) used.
|
|
627
|
+
Many manufacturers don't specify this information explicitly.
|
|
628
|
+
However, these values can be inferred from:
|
|
629
|
+
|
|
630
|
+
- the number of bypass diodes
|
|
631
|
+
- where and how many junction boxes are present on the back of the module
|
|
632
|
+
- whether or not the module is comprised of *half-cut cells*
|
|
633
|
+
|
|
634
|
+
The latter two are heavily correlated.
|
|
635
|
+
|
|
636
|
+
For example:
|
|
637
|
+
|
|
638
|
+
1. A module with 1 bypass diode behaves as 1 block.
|
|
639
|
+
2. A module with 3 bypass diodes and 1 junction box is likely to have 3
|
|
640
|
+
blocks.
|
|
641
|
+
3. A half-cut module with 3 junction boxes (split junction boxes) is
|
|
642
|
+
likely to have 3x2 blocks. The number of blocks along the longest
|
|
643
|
+
side of the module is 2 and along the shortest side is 3.
|
|
644
|
+
4. A module without bypass diodes doesn't constitute a block, but may be
|
|
645
|
+
part of one.
|
|
646
|
+
|
|
647
|
+
Examples
|
|
648
|
+
--------
|
|
649
|
+
Minimal example. For a complete example, see
|
|
650
|
+
:ref:`sphx_glr_gallery_shading_plot_martinez_shade_loss.py`.
|
|
651
|
+
|
|
652
|
+
>>> import numpy as np
|
|
653
|
+
>>> from pvlib import shading
|
|
654
|
+
>>> total_blocks = 3 # blocks along the vertical of the module
|
|
655
|
+
>>> POA_direct_and_circumsolar, POA_diffuse = 600, 80 # W/m²
|
|
656
|
+
>>> POA_global = POA_direct_and_circumsolar + POA_diffuse
|
|
657
|
+
>>> P_out_unshaded = 3000 # W
|
|
658
|
+
>>> # calculation of the shaded fraction for the collector
|
|
659
|
+
>>> shaded_fraction = shading.shaded_fraction1d(
|
|
660
|
+
>>> solar_zenith=80, solar_azimuth=180,
|
|
661
|
+
>>> axis_azimuth=90, shaded_row_rotation=25,
|
|
662
|
+
>>> collector_width=0.5, pitch=1, surface_to_axis_offset=0,
|
|
663
|
+
>>> cross_axis_slope=5.711, shading_row_rotation=50)
|
|
664
|
+
>>> # calculation of the number of shaded blocks
|
|
665
|
+
>>> shaded_blocks = np.ceil(total_blocks*shaded_fraction)
|
|
666
|
+
>>> # apply the Martinez power losses to the calculated shading
|
|
667
|
+
>>> loss_fraction = shading.direct_martinez(
|
|
668
|
+
>>> POA_global, POA_direct_and_circumsolar,
|
|
669
|
+
>>> shaded_fraction, shaded_blocks, total_blocks)
|
|
670
|
+
>>> P_out_corrected = P_out_unshaded * (1 - loss_fraction)
|
|
671
|
+
|
|
672
|
+
See Also
|
|
673
|
+
--------
|
|
674
|
+
shaded_fraction1d : to calculate 1-dimensional shaded fraction
|
|
675
|
+
|
|
676
|
+
References
|
|
677
|
+
----------
|
|
678
|
+
.. [1] F. Martínez-Moreno, J. Muñoz, and E. Lorenzo, 'Experimental model
|
|
679
|
+
to estimate shading losses on PV arrays', Solar Energy Materials and
|
|
680
|
+
Solar Cells, vol. 94, no. 12, pp. 2298-2303, Dec. 2010,
|
|
681
|
+
:doi:`10.1016/j.solmat.2010.07.029`.
|
|
682
|
+
""" # Contributed by Echedey Luis, 2024
|
|
683
|
+
beam_factor = ( # Eq. (6) of [1]
|
|
684
|
+
(1 - shaded_fraction)
|
|
685
|
+
* (1 - np.ceil(shaded_blocks) / (1 + total_blocks))
|
|
686
|
+
)
|
|
687
|
+
return ( # Eq. (8) of [1]
|
|
688
|
+
1
|
|
689
|
+
- (
|
|
690
|
+
poa_direct * beam_factor
|
|
691
|
+
+ (poa_global - poa_direct) # diffuse and albedo
|
|
692
|
+
)
|
|
693
|
+
/ poa_global
|
|
694
|
+
)
|
pvlib/spectrum/__init__.py
CHANGED
|
@@ -2,8 +2,13 @@ from pvlib.spectrum.spectrl2 import spectrl2 # noqa: F401
|
|
|
2
2
|
from pvlib.spectrum.mismatch import ( # noqa: F401
|
|
3
3
|
calc_spectral_mismatch_field,
|
|
4
4
|
get_am15g,
|
|
5
|
+
get_reference_spectra,
|
|
5
6
|
get_example_spectral_response,
|
|
6
7
|
spectral_factor_caballero,
|
|
7
8
|
spectral_factor_firstsolar,
|
|
8
9
|
spectral_factor_sapm,
|
|
10
|
+
spectral_factor_pvspec,
|
|
11
|
+
spectral_factor_jrc,
|
|
12
|
+
sr_to_qe,
|
|
13
|
+
qe_to_sr
|
|
9
14
|
)
|