forked from calico/calicolabs-piccolo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfcs_generator.py
122 lines (108 loc) · 3.5 KB
/
fcs_generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import struct
import numpy as np
def generate_random_events(events, parameters):
# Generate a NumPy array of random floats
events = np.random.rand(events, parameters) * 1024 # Scale to 0-1024
return events
def create_fcs32_template(filename):
# Initial header with placeholders
header = (
"FCS3.2 " # FCS version
" " # Text start
" " # Text end
" " # Data start
" " # Data end
" " # Analysis start
" " # Analysis end
)
# Example values for the text segment
num_events = 1000 # Total number of events (EDIT)
num_parameters = 3 # Number of measurements per event (EDIT?)
random_events = generate_random_events(num_events, num_parameters)
random_events_list = random_events.tolist()
# Placeholder for TEXT segment with newline characters for readability
text_segment = (
"$BEGINDATA878"
"$ENDDATA12877"
"$BEGINSTEXT257"
"$ENDSTEXT877"
"$BYTEORD1,2,3,4"
"$CELLSDROPLETS"
"$CYTFADS"
"$DATATYPEF"
"$EXPTobias Wenzel"
"INSTIIBM"
"$NEXTDATA0"
f"$PAR{num_parameters}"
f"$TOT{num_events}"
"$P1B32"
"P1DETSP1"
"$P1E0.0"
"$P1FEATUREArea"
f"P1G0" #Edit
"P1L405"
"$P1Npeak1"
f"$P1O0" #Edit
"$P1R1024"
"$P1TPM3315-WL SiPM"
"$P1TAGDAPI"
"$P1TYPERaw Fluorescence"
f"$P1V0" #Edit
"$P2B32"
"P2DETSP2"
"$P2E0.0"
"$P2FEATUREArea"
f"P2G0" #Edit
"P2L488"
"$P2Npeak2"
f"$P2O0" #Edit
"$P2R1024"
"$P2TPM3315-WL SiPM"
"$P2TAGGFP"
"$P2TYPERaw Fluorescence"
f"$P2V0" #Edit
"$P3B32"
"P3DETSP3"
"$P3E0.0"
"$P3FEATUREArea"
f"P3G0" #Edit
"P3L638"
"$P3Npeak3"
f"$P3O0" #Edit
"$P3R1024"
"$P3TPM3315-WL SiPM"
"$P3TAGActin" #Maybe?
"$P1TYPERaw Fluorescence"
f"$P3V0" #Edit
)
# Example data for the DATA segment
data = random_events_list
# Pack the data into binary format
data_segment = b''.join(struct.pack('fff', *event) for event in data)
# Placeholder for ANALYSIS segment (empty in this example)
analysis_segment = b''
# Calculate positions
text_start = 257 # Start after the header
text_end = text_start + len(text_segment) - 1
data_start = text_end + 1
data_end = data_start + len(data_segment) - 1
analysis_start = 0 # Not used in this example
analysis_end = 0 # Not used in this example
# Update header with correct positions and pad to 256 bytes
header = (
f"FCS3.2 " # FCS version
f"{text_start: 8d}" # Text start position
f"{text_end: 8d}" # Text end position
f"{data_start: 8d}" # Data start position
f"{data_end: 8d}" # Data end position
f"{analysis_start: 8d}" # Analysis start (optional)
f"{analysis_end: 8d}" # Analysis end (optional)
).ljust(256, ' ') # Ensure the header is 256 bytes
# Write to file
with open(filename, 'wb') as f:
f.write(header.encode('ascii'))
f.write(text_segment.encode('ascii'))
f.write(data_segment)
f.write(analysis_segment)
# Usage
create_fcs32_template('template.fcs')