tube improvements

This commit is contained in:
Bane Stojkovic
2026-11-02 14:40:23 +01:00
parent 1dfef6dd6b
commit 3e043a8387
10 changed files with 611 additions and 216 deletions
@@ -30,6 +30,8 @@ import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.StringUtils;
@@ -38,8 +40,10 @@ import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractAngledComponent;
import org.diylc.components.AbstractMakerBoard;
import org.diylc.components.transform.AngledComponentTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IDatasheetSupport;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -55,11 +59,15 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@AiNote("The first control point is the socket centre, not a pin. Pins sit on a circle and are numbered clockwise, starting after the gap (B9A, B7G, B12C) or the key (OCTAL), which points right at 'Angle' 0; 'Angle' rotates the socket clockwise in degrees. This is the bottom view used for wiring")
@AiNote("'Electrode Labels' is a comma-separated list of electrode names in pin order starting at pin 1: P plate, G triode grid, G1/G2/G3 control, screen and suppressor grids, K cathode, BP beam plates, IS internal shield, HCT heater centre tap. Sections of a multi-section tube are numbered first (1P, 1G, 2P); heater ends are named after their pin (H4, H5) because they are separate nets; pins joined inside the tube end in _1, _2; NC and IC pins are never connected")
@AiNote("A datasheet model is a tube type such as 12AX7 or EL34 and sets 'Base', 'Electrode Labels' and 'Designation'. Set 'Designation' to the same tube type together with the model")
@ComponentDescriptor(name = "Tube Socket", author = "Branislav Stojkovic", category = "Tubes",
instanceNamePrefix = "V", description = "Various types of tube/valve sockets",
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true,
transformer = AngledComponentTransformer.class)
public class TubeSocket extends AbstractAngledComponent<String> implements IGerberComponentSimple {
transformer = AngledComponentTransformer.class, enableDatasheet = true,
datasheetCreationStepCount = 2, datasheetModelColumn = 1)
public class TubeSocket extends AbstractAngledComponent<String>
implements IGerberComponentSimple, IDatasheetSupport {
private static final Size B9A_PIN_SPACING_CHASSIS = new Size(12.5d, SizeUnit.mm);
private static final Size B9A_PIN_SPACING_PCB = new Size(21d, SizeUnit.mm);
@@ -103,6 +111,21 @@ public class TubeSocket extends AbstractAngledComponent<String> implements IGerb
updateControlPoints();
}
public TubeSocket(String[] model) {
this();
applyModel(model);
}
// columns: group, tube type, base, RETMA basing code, then one electrode name per pin in pin
// order
@Override
public void applyModel(String[] model) {
setValue(model[1]);
setBase(Base.valueOf(model[2]));
setElectrodeLabels(String.join(",", Arrays.copyOfRange(model, 4, model.length)));
}
@EditableProperty
public Base getBase() {
return base;
@@ -304,7 +327,7 @@ public class TubeSocket extends AbstractAngledComponent<String> implements IGerb
double electrodeLabelOffset = project.getFont().getSize2D() * (getBase() == Base.B9A && getMount() == Mount.PCB ? 1.5 : 1);
for (int i = 0; i < labels.length; i++) {
if (i < controlPoints.length - 1) {
String label = labels[i];
String label = AbstractMakerBoard.getDisplayPinLabel(labels[i]);
double theta = Math.atan2(controlPoints[i + 1].getY() - controlPoints[0].getY(), controlPoints[i + 1].getX() - controlPoints[0].getX());
double x = controlPoints[i + 1].getX() - Math.cos(theta) * electrodeLabelOffset;
double y = controlPoints[i + 1].getY() - Math.sin(theta) * electrodeLabelOffset;
@@ -0,0 +1,188 @@
Dual Triode,12AX7,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,ECC83,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,7025,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,5751,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,12AT7,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,ECC81,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,12AU7,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,ECC82,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,12AY7,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,6072,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,12BH7,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,12DW7,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,12AZ7,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,5965,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,ECC99,B9A,9A,2P,2G,2K,H4,H5,1P,1G,1K,HCT
Dual Triode,6922,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,E88CC,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,6DJ8,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,ECC88,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,7308,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,6CG7,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,ECC85,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,6FQ7,B9A,9LP,2P,2G,2K,H4,H5,1P,1G,1K,NC
Dual Triode,5687,B9A,9H,2P,2G,2K,H4,H5,1K,1G,HCT,1P
Dual Triode,6N1P,B9A,-,1P,1G,1K,H4,H5,2P,2G,2K,IS
Dual Triode,6N2P,B9A,-,1P,1G,1K,H4,H5,2P,2G,2K,IS
Dual Triode,6H30P,B9A,-,1P,1G,1K,H4,H5,2P,2G,2K,IS
Dual Triode,6SN7,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6SL7,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6080,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6AS7,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6BX7,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6BL7,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Triode,12B4A,B9A,9AG,K,G_1,HCT,H4,H5,NC,G_2,NC,P
Triode,6J5,OCTAL,6Q,SH,H2,P,NC,G,NC,H7,K
Triode,6C5,OCTAL,6Q,SH,H2,P,NC,G,NC,H7,K
Pentode,EF86,B9A,9CQ,G2,IS_1,K,H4,H5,P,IS_2,G3,G1
Pentode,6267,B9A,9CQ,G2,IS_1,K,H4,H5,P,IS_2,G3,G1
Pentode,5879,B9A,9AD,G1,NC,K,H4,H5,NC,G2,P,G3
Pentode,EF80,B9A,9AQ,K_1,G1,K_2,H4,H5,IS,P,G2,G3
Pentode,EF184,B9A,9AQ,K_1,G1,K_2,H4,H5,IS,P,G2,G3
Pentode,6AU6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Pentode,6BA6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Pentode,6AK5,B7G,7BD,G1,K_1,H3,H4,P,G2,K_2
Pentode,6SJ7,OCTAL,8N,SH,H2,G3,G1,K,G2,H7,P
Converter,12BE6,B7G,7CH,G1,K,H3,H4,P,G2,G3
Converter,6BE6,B7G,7CH,G1,K,H3,H4,P,G2,G3
Pentode (RF/IF),12BA6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Pentode (RF/IF),6BD6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Diode-Triode,12AV6,B7G,7BT,TG,K,H3,H4,2D,1D,TP
Diode-Triode,12AT6,B7G,7BT,TG,K,H3,H4,2D,1D,TP
Diode-Triode,6AV6,B7G,7BT,TG,K,H3,H4,2D,1D,TP
Diode-Triode,6AT6,B7G,7BT,TG,K,H3,H4,2D,1D,TP
Beam Tetrode,50C5,B7G,7CV,K,G1_1,H3,H4,G1_2,G2,P
Rectifier,35W4,B7G,5BQ,NC,NC,H3,H4,P,HT,K
Converter,6SA7,OCTAL,8R,G5,H2,P,G2,G1,K,H7,G3
Converter,12SA7,OCTAL,8R,G5,H2,P,G2,G1,K,H7,G3
Pentode (RF/IF),6SK7,OCTAL,8N,SH,H2,G3,G1,K,G2,H7,P
Pentode (RF/IF),12SK7,OCTAL,8N,SH,H2,G3,G1,K,G2,H7,P
Pentode (RF/IF),6SG7,OCTAL,8BK,SH,H2,K_1,G1,K_2,G2,H7,P
Diode-Triode,6SQ7,OCTAL,8Q,SH,TG,K,2D,1D,TP,H7,H8
Diode-Triode,12SQ7,OCTAL,8Q,SH,TG,K,2D,1D,TP,H7,H8
Beam Tetrode,50L6GT,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Rectifier,35Z5GT,OCTAL,6AD,NC,H2,HT,NC,P,NC,H7,K
Converter,ECH81,B9A,9CA,HG2,HG1,K,H4,H5,HP,HG3,TP,TG
Converter,ECH83,B9A,9CA,HG2,HG1,K,H4,H5,HP,HG3,TP,TG
Converter,UCH81,B9A,9CA,HG2,HG1,K,H4,H5,HP,HG3,TP,TG
Pentode (RF/IF),EF85,B9A,9AQ,K_1,G1,K_2,H4,H5,IS,P,G2,G3
Diode-Pentode,EBF89,B9A,9HE,PG2,PG1,K,H4,H5,PP,1D,2D,PG3
Diode-Pentode,UBF89,B9A,9HE,PG2,PG1,K,H4,H5,PP,1D,2D,PG3
Diode-Triode,EABC80,B9A,9E,3D,2D,2DK,H4,H5,1D,K,TG,TP
Triode-Pentode,UCL82,B9A,9EX,TG,PK,PG1,H4,H5,PP,PG2,TK,TP
Tuning Indicator,EM84,B9A,9GA,G,IC,K,H4,H5,TA,DE,IC,P
Tuning Indicator,EM80,B9A,9DB,G,K,IC,H4,H5,IC,P,IC,TA
Tuning Indicator,EM81,B9A,9DB,G,K,IC,H4,H5,IC,P,IC,TA
Tuning Indicator,6AF6,OCTAL,7AG,NC,H2,2RC,1RC,TA,NC,H7,K
Tuning Indicator,1629,OCTAL,7AL,NC,H2,P,TA,G,NC,H7,K
Space-Charge,12K5,B7G,7FD,K,G2,H3,H4,G1_1,G1_2,P
Space-Charge,12AD6,B7G,7CH,G1,K,H3,H4,P,G2,G3
Space-Charge,12EG6,B7G,7CH,G1,K,H3,H4,P,G2,G3
Space-Charge,12AF6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Space-Charge,12CX6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Space-Charge,12DZ6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Space-Charge,12EK6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Space-Charge,12AC6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Space-Charge,12BL6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Space-Charge,12AE6,B7G,7BT,TG,K,H3,H4,2D,1D,TP
Space-Charge,12FM6,B7G,7BT,TG,K,H3,H4,2D,1D,TP
Space-Charge,12FK6,B7G,7BT,TG,K,H3,H4,2D,1D,TP
Space-Charge,12EL6,B7G,7FB,TG,TP,H3,H4,2D,1D,K
Space-Charge,12FX8,B9A,9KV,HG2,HG1,HP,H4,H5,TG,HK,TP,HG3
Space-Charge,12DS7,B9A,9JU,2D,NC,G1,H4,H5,P,G2,K,1D
Space-Charge,12EM6,B9A,9HV,G1,K,G2,H4,H5,P,IC,IC,D
Space-Charge,12J8,B9A,9GC,G1,K,G2,H4,H5,P,DK,2D,1D
Space-Charge,12DL8,B9A,9HR,2D,K,G1,H4,H5,P,G2,DK,1D
Power Pentode,EL84,B9A,9CV,IC,G1,K,H4,H5,IC,P,IC,G2
Power Pentode,6BQ5,B9A,9CV,IC,G1,K,H4,H5,IC,P,IC,G2
Power Pentode,7189,B9A,9CV,IC,G1,K,H4,H5,IC,P,IC,G2
Power Pentode,7189A,B9A,9LE,G1_1,G1_2,K,H4,H5,G2_1,P,IC,G2_2
Power Pentode,6CW5,B9A,9CV,IC,G1,K,H4,H5,IC,P,IC,G2
Power Pentode,EL86,B9A,9CV,IC,G1,K,H4,H5,IC,P,IC,G2
Beam Tetrode,6V6GT,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6V6,OCTAL,7AC,SH,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6L6GC,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6L6,OCTAL,7AC,SH,H2,P,G2,G1,NC,H7,K
Beam Tetrode,5881,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,7581A,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,KT66,OCTAL,7AC,IC,H2,P,G2,G1,NC,H7,K
Power Pentode,EL34,OCTAL,8ET,G3,H2,P,G2,G1,NC,H7,K
Power Pentode,6CA7,OCTAL,8ET,G3,H2,P,G2,G1,NC,H7,K
Beam Tetrode,KT88,OCTAL,7AC,SH,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6550,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,KT120,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,KT150,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Power Pentode,7591,OCTAL,8KG,NC,H2,P,G2_1,K,G1,H7,G2_2
Beam Tetrode,6AQ5,B7G,7BZ,G1_1,K,H3,H4,P,G2,G1_2
Beam Tetrode,6BF5,B7G,7BZ,G1_1,K,H3,H4,P,G2,G1_2
Beam Tetrode,50B5,B7G,7BZ,G1_1,K,H3,H4,P,G2,G1_2
Beam Tetrode,6973,B9A,9EU,G2_1,NC,G1_1,H4,H5,G1_2,K,G2_2,P
Beam Tetrode,12AB5,B9A,9EU,G2_1,NC,G1_1,H4,H5,G1_2,K,G2_2,P
Triode-Pentode,6BM8,B9A,9EX,TG,PK,PG1,H4,H5,PP,PG2,TK,TP
Triode-Pentode,ECL82,B9A,9EX,TG,PK,PG1,H4,H5,PP,PG2,TK,TP
Triode-Pentode,ECL86,B9A,9LZ,TG,TK,PG2,H4,H5,PP,PK,PG1,TP
Triode-Pentode,6GW8,B9A,9LZ,TG,TK,PG2,H4,H5,PP,PK,PG1,TP
Power Pentode,6F6G,OCTAL,7S,NC,H2,P,G2,G1,NC,H7,K
Power Pentode,6K6GT,OCTAL,7S,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6Y6G,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6AS5,B7G,7CV,K,G1_1,H3,H4,G1_2,G2,P
Beam Tetrode,6CU5,B7G,7CV,K,G1_1,H3,H4,G1_2,G2,P
Beam Tetrode,35C5,B7G,7CV,K,G1_1,H3,H4,G1_2,G2,P
Power Pentode,6EH5,B7G,7CV,K,G1_1,H3,H4,G1_2,G2,P
Beam Tetrode,6CZ5,B9A,9HN,G2,NC,G1_1,H4,H5,G1_2,K,IC,P
Beam Tetrode,6EM5,B9A,9HN,G2,NC,G1_1,H4,H5,G1_2,K,IC,P
Beam Tetrode,6BW6,B9A,9AM,IC,G1,K,H4,H5,NC,P,G2,BP
Power Pentode,6DL5,B7G,7DQ,G1_1,K,H3,H4,P,G2,G1_2
Power Pentode,EL95,B7G,7DQ,G1_1,K,H3,H4,P,G2,G1_2
Power Pentode,6AK6,B7G,7BK,G1,G3,H3,H4,P,G2,K
Power Pentode,6AR5,B7G,6CC,G1,K,H3,H4,P,G2,NC
Beam Tetrode,6CM6,B9A,9CK,G2,NC,G1_1,H4,H5,G1_2,K,NC,P
Power Pentode,6CL6,B9A,9BV,K,G1_1,G2_1,H4,H5,P,G3,G2_2,G1_2
Rectifier,5AR4,OCTAL,5L,IC,H2,NC,1P,NC,2P,NC,HK8
Rectifier,GZ34,OCTAL,5L,IC,H2,NC,1P,NC,2P,NC,HK8
Rectifier,5V4G,OCTAL,5L,NC,H2,NC,1P,NC,2P,NC,HK8
Rectifier,GZ32,OCTAL,5L,NC,H2,NC,1P,NC,2P,NC,HK8
Rectifier,5Y3GT,OCTAL,5T,NC,F2,NC,2P,NC,1P,NC,F8
Rectifier,5U4GB,OCTAL,5T,NC,F2,NC,2P,NC,1P,NC,F8
Rectifier,EZ81,B9A,9M,1P,IC,K,H4,H5,IC,2P,IC,IC
Rectifier,EZ80,B9A,9M,1P,IC,K,H4,H5,IC,2P,IC,IC
Rectifier,6CA4,B9A,9M,1P,NC,K,H4,H5,NC,2P,NC,NC
Rectifier,6X4,B7G,7CF,2P,NC,H3,H4,NC,1P,K
Rectifier,6X5GT,OCTAL,6S,NC,H2,2P,NC,1P,NC,H7,K
Rectifier,6X5,OCTAL,6S,SH,H2,2P,NC,1P,NC,H7,K
Rectifier,6AX5GT,OCTAL,6S,NC,H2,2P,NC,1P,NC,H7,K
Voltage Reference,0A2,B7G,5BO,P_1,K_1,IC,K_2,P_2,IC,K_3
Voltage Reference,0B2,B7G,5BO,P_1,K_1,IC,K_2,P_2,IC,K_3
Voltage Reference,0D3,OCTAL,4AJ,NC,K,J_1,NC,P,NC,J_2,NC
Voltage Reference,0C3,OCTAL,4AJ,NC,K,J_1,NC,P,NC,J_2,NC
Voltage Reference,0A3,OCTAL,4AJ,NC,K,J_1,NC,P,NC,J_2,NC
Dual Triode,6N2P-EV,B9A,-,1P,1G,1K,H4,H5,2P,2G,2K,IS
Dual Triode,6N1P-EV,B9A,-,1P,1G,1K,H4,H5,2P,2G,2K,IS
Dual Triode,6N6P,B9A,-,1P,1G,1K,H4,H5,2P,2G,2K,IS
Dual Triode,6N23P,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,6N23P-EV,B9A,9AJ,2P,2G,2K,H4,H5,1P,1G,1K,IS
Dual Triode,6N24P,B9A,-,2K,2G,2P,H4,H5,1G,1K_1,1K_2,1P
Dual Triode,6N3P,B9A,-,H1,1K,1G,1P,IS,2P,2G,2K,H9
Dual Triode,6N8S,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6N9S,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6N13S,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Dual Triode,6N5S,OCTAL,8BD,2G,2P,2K,1G,1P,1K,H7,H8
Triode,6S45P,B9A,-,K_1,G_1,K_2,H4,H5,K_3,P,G_2,K_4
Power Triode,6S19P,B9A,-,P_1,G_1,P_2,H4,H5,P_3,G_2,P_4,K
Power Triode,6S4S,OCTAL,5S,NC,F2,P,NC,G,NC,F7,NC
Pentode,6Zh32P,B9A,9CQ,G2,IS_1,K,H4,H5,P,IS_2,G3,G1
Pentode,6Zh1P,B7G,-,G1,K_1,H3,H4,P,G2,K_2
Power Pentode,6P14P,B9A,9CV,NC,G1,K,H4,H5,NC,P,NC,G2
Power Pentode,6P14P-EV,B9A,9CV,NC,G1,K,H4,H5,NC,P,NC,G2
Power Pentode,6P18P,B9A,9CV,NC,G1,K,H4,H5,NC,P,NC,G2
Power Pentode,6P15P,B9A,-,G3_1,G1,K,H4,H5,G3_2,P,NC,G2
Power Pentode,EL91,B7G,-,G1,K,H3,H4,P,NC,G2
Power Pentode,6AM5,B7G,-,G1,K,H3,H4,P,NC,G2
Beam Tetrode,6P1P,B9A,-,P_1,G2_1,K_1,H4,H5,P_2,G1,K_2,G2_2
Beam Tetrode,6P3S,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6P3S-E,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6P6S,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Beam Tetrode,6P27S,OCTAL,7AC,NC,H2,P,G2,G1,NC,H7,K
Rectifier,5C3S,OCTAL,5T,NC,F2,NC,2P,NC,1P,NC,F8
Rectifier,5C4S,OCTAL,5L,NC,H2,NC,1P,NC,2P,NC,HK8
Rectifier,6C4P,B7G,-,1P,NC,H3,H4,K,NC,2P
@@ -0,0 +1,117 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.components.tube;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.diylc.netlist.Node;
import org.diylc.presenter.DatasheetService;
import org.junit.Assert;
import org.junit.Test;
public class TubeSocketDatasheetTest {
private static final int FIRST_PIN_COLUMN = 4;
private static final Set<String> UNUSED_PIN_NAMES =
new HashSet<String>(Arrays.asList("NC", "IC", "SH"));
@Test
public void everyRowNamesEveryPinOfItsBase() {
for (String[] row : datasheet()) {
TubeSocket socket = new TubeSocket(row);
String context = String.join(",", row);
Assert.assertEquals(context, row[1], socket.getValue());
// control point 0 is the socket centre
Assert.assertEquals(context, row.length - FIRST_PIN_COLUMN,
socket.getControlPointCount() - 1);
}
}
@Test
public void designationsAreUnique() {
Set<String> tubes = new HashSet<String>();
for (String[] row : datasheet()) {
Assert.assertTrue("repeated tube " + row[1], tubes.add(row[1].toUpperCase()));
}
}
/** Two pins share a net only when both say so with a numbered suffix, like K_3 and K_8. */
@Test
public void pinsShareANetOnlyThroughTheSuffix() {
for (String[] row : datasheet()) {
for (int i = FIRST_PIN_COLUMN; i < row.length; i++) {
for (int j = i + 1; j < row.length; j++) {
String rail = Node.railName(row[i]);
if (rail != null && rail.equals(Node.railName(row[j]))) {
Assert.assertTrue(row[1] + " pins " + row[i] + " and " + row[j],
row[i].matches(".*_\\d+") && row[j].matches(".*_\\d+"));
}
}
}
}
}
/** A basing code fixes what each pin is, so every tube on one basing names its pins alike. */
@Test
public void tubesOnOneBasingNameTheirPinsAlike() {
Map<String, String[]> byBasing = new HashMap<String, String[]>();
for (String[] row : datasheet()) {
// "-" marks a tube with no RETMA basing, e.g. most Soviet types
if (row[3].equals("-")) {
continue;
}
String key = row[2] + " " + row[3];
String[] names = Arrays.copyOfRange(row, FIRST_PIN_COLUMN, row.length);
// a basing fixes the electrodes; an unused pin is the metal shell, a no-connect or an
// internal connection depending on the envelope and the maker
for (int i = 0; i < names.length; i++) {
if (UNUSED_PIN_NAMES.contains(names[i])) {
names[i] = "unused";
}
}
String[] first = byBasing.putIfAbsent(key, names);
if (first != null) {
Assert.assertArrayEquals(row[1] + " on " + key, first, names);
}
}
}
@Test
public void tubeIsFoundByTypeNotByGroup() {
DatasheetService service = DatasheetService.getInstance();
String[] first = datasheet().get(0);
Assert.assertEquals(1, service.findSeries(TubeSocket.class, first[1]).size());
Assert.assertTrue(service.findSeries(TubeSocket.class, first[0]).isEmpty());
}
private static List<String[]> datasheet() {
List<String[]> datasheet = DatasheetService.getInstance().loadDatasheet(TubeSocket.class);
Assert.assertNotNull(datasheet);
Assert.assertFalse(datasheet.isEmpty());
return datasheet;
}
}
@@ -0,0 +1,49 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.components.tube;
import org.diylc.components.tube.TubeSocket.Base;
import org.diylc.components.tube.TubeSocket.Mount;
import org.diylc.core.Angle;
import org.junit.Assert;
import org.junit.Test;
public class TubeSocketTest {
@Test
public void modelSetsBaseLabelsAndDesignation() {
TubeSocket socket = new TubeSocket();
socket.setMount(Mount.PCB);
socket.setAngle(Angle.of(45));
socket.applyModel(new String[] {"Power Pentode", "TEST", "OCTAL", "8XX", "NC", "H2", "P",
"G2", "G1", "NC", "H7", "K"});
Assert.assertEquals("TEST", socket.getValue());
Assert.assertEquals(Base.OCTAL, socket.getBase());
Assert.assertEquals("NC,H2,P,G2,G1,NC,H7,K", socket.getElectrodeLabels());
Assert.assertEquals(Mount.PCB, socket.getMount());
Assert.assertEquals(Angle.of(45), socket.getAngle());
// control point 0 is the socket centre, so pin 1 is control point 1
Assert.assertEquals("H2", socket.getControlPointNodeName(2));
Assert.assertEquals("K", socket.getControlPointNodeName(8));
}
}