77
88namespace pflib ::algorithm {
99
10- /* *
11- * Retrieve the ADC sample for the input channel from the input event packet
12- */
13- static int get_adc (const pflib::packing::MultiSampleECONDEventPacket& p,
14- int ch) {
15- // Use link specific channel calculation
16- // TODO: 348
17- // Use the "Sample Of Interest" inside the EventPacket
18- // TODO this is only true if we only have one ROC's channels enabled
19- // in the ECON-D. In the more realistic case, we should get the
20- // link indices depending on which ROC we are aligning
21- int i_link = ch / 36 ; // 0 or 1
22- int i_ch = ch % 36 ; // 0 - 35
23-
24- // ECONDEventPacket.h defines channel differently to SingleROCEventPacket.h
25- // because it can have more than 2 links readout
26- return p.samples [p.i_soi ].channel (i_link, i_ch).adc ();
27- }
28-
2910/* *
3011 * get the medians of the channel ADC values
3112 *
@@ -59,8 +40,8 @@ static std::array<int, 72> get_adc_medians(
5940 return medians;
6041}
6142
62- std::map<std::string, std::map<std::string, uint64_t >> level_pedestals (
63- Target* tgt, ROC roc ) {
43+ std::map<int , std::map<std:: string, std::map<std::string, uint64_t >>>
44+ level_pedestals ( Target* tgt) {
6445 static auto the_log_{::pflib::logging::get (" level_pedestals" )};
6546
6647 // / do three runs of 100 samples each to have well defined pedestals
@@ -70,118 +51,166 @@ std::map<std::string, std::map<std::string, uint64_t>> level_pedestals(
7051 pflib_log (info) << " Using DAQ format mode: "
7152 << static_cast <int >(pftool::state.daq_format_mode );
7253
73- std::array<int , 2 > target;
74- std::array<int , 72 > baseline, highend, lowend;
54+ // each output stream ("half" of a ROC) has its own target pedestal value
55+ std::map<int , std::array<int , 2 >> target;
56+ // each channel has measurements at different parameter points
57+ std::map<int , std::array<int , 72 >> baseline, highend, lowend;
7558
76- // / TODO for multi-ROC set ups, we could dynamically determine the number
77- // of ROCs and the number of channels from the Target
78- DecodeAndBuffer buffer{n_events, 2 };
59+ DecodeAndBuffer buffer{n_events, tgt->nrocs ()*2 };
7960
8061 { // baseline run scope
8162 pflib_log (info) << " 100 event baseline run" ;
82- auto test_handle = roc.testParameters ()
83- .add_all_channels (" SIGN_DAC" , 0 )
84- .add_all_channels (" DACB" , 0 )
85- .add_all_channels (" TRIM_INV" , 0 )
86- .apply ();
63+
64+ std::map<std::string, std::map<std::string, uint64_t >> parameters;
65+ for (int ch{0 }; ch < 72 ; ch++) {
66+ std::string ch_str{" CH_" +std::to_string (ch)};
67+ parameters[ch_str][" SIGN_DAC" ] = 0 ;
68+ parameters[ch_str][" DACB" ] = 0 ;
69+ parameters[ch_str][" TRIM_INV" ] = 0 ;
70+ }
71+
72+ std::map<int , std::map<int , std::map<int , uint8_t >>> prior_registers;
73+ for (int i_roc : tgt->roc_ids ()) {
74+ prior_registers[i_roc] = tgt->roc (i_roc).applyParameters (parameters);
75+ }
76+
8777 daq_run (tgt, " PEDESTAL" , buffer, n_events, 100 );
8878 pflib_log (trace) << " baseline run done, getting channel medians" ;
89- auto medians = get_adc_medians (buffer.get_buffer ());
79+ std::map<int , std::array<int , 72 >> medians;
80+ for (int i_roc : tgt->roc_ids ()) {
81+ medians[i_roc] = get_adc_medians (i_roc, tgt->getRocErxMapping (), buffer.get_buffer ());
82+ }
9083 baseline = medians;
9184 pflib_log (trace) << " got channel medians, getting link medians" ;
92- for (int i_link{0 }; i_link < 2 ; i_link++) {
93- auto start{medians.begin () + 36 * i_link};
94- auto end{start + 36 };
95- auto halfway{start + 18 };
96- std::nth_element (start, halfway, end);
97- target[i_link] = *halfway;
85+ for (int i_half{0 }; i_half < 2 ; i_half++) {
86+ for (int i_roc : tgt->roc_ids ()) {
87+ auto start{medians.at (i_roc).begin () + 36 * i_half};
88+ auto end{start + 36 };
89+ auto halfway{start + 18 };
90+ std::nth_element (start, halfway, end);
91+ target[i_roc][i_half] = *halfway;
92+ }
93+ }
94+ pflib_log (trace) << " got medians per half" ;
95+
96+ for (int i_roc : tgt->roc_ids ()) {
97+ tgt->roc (i_roc).setRegisters (prior_registers.at (i_roc));
9898 }
99- pflib_log (trace) << " got link medians" ;
10099 }
101100
102101 { // highend run scope
103102 pflib_log (info) << " 100 event highend run" ;
104- auto test_handle = roc.testParameters ()
105- .add_all_channels (" SIGN_DAC" , 0 )
106- .add_all_channels (" DACB" , 0 )
107- .add_all_channels (" TRIM_INV" , 63 )
108- .apply ();
103+
104+ std::map<std::string, std::map<std::string, uint64_t >> parameters;
105+ for (int ch{0 }; ch < 72 ; ch++) {
106+ std::string ch_str{" CH_" +std::to_string (ch)};
107+ parameters[ch_str][" SIGN_DAC" ] = 0 ;
108+ parameters[ch_str][" DACB" ] = 0 ;
109+ parameters[ch_str][" TRIM_INV" ] = 63 ;
110+ }
111+
112+ std::map<int , std::map<int , std::map<int , uint8_t >>> prior_registers;
113+ for (int i_roc : tgt->roc_ids ()) {
114+ prior_registers[i_roc] = tgt->roc (i_roc).applyParameters (parameters);
115+ }
116+
109117 daq_run (tgt, " PEDESTAL" , buffer, n_events, 100 );
110- highend = get_adc_medians (buffer.get_buffer ());
118+
119+ for (int i_roc : tgt->roc_ids ()) {
120+ highend[i_roc] = get_adc_medians (i_roc, tgt->getRocErxMapping (), buffer.get_buffer ());
121+ }
122+
123+ for (int i_roc : tgt->roc_ids ()) {
124+ tgt->roc (i_roc).setRegisters (prior_registers.at (i_roc));
125+ }
111126 }
112127
113128 { // lowend run
114129 pflib_log (info) << " 100 event lowend run" ;
115- auto test_handle = roc.testParameters ()
116- .add_all_channels (" SIGN_DAC" , 1 )
117- .add_all_channels (" DACB" , 31 )
118- .add_all_channels (" TRIM_INV" , 0 )
119- .apply ();
130+
131+ std::map<std::string, std::map<std::string, uint64_t >> parameters;
132+ for (int ch{0 }; ch < 72 ; ch++) {
133+ std::string ch_str{" CH_" +std::to_string (ch)};
134+ parameters[ch_str][" SIGN_DAC" ] = 1 ;
135+ parameters[ch_str][" DACB" ] = 31 ;
136+ parameters[ch_str][" TRIM_INV" ] = 0 ;
137+ }
138+
139+ std::map<int , std::map<int , std::map<int , uint8_t >>> prior_registers;
140+ for (int i_roc : tgt->roc_ids ()) {
141+ prior_registers[i_roc] = tgt->roc (i_roc).applyParameters (parameters);
142+ }
143+
120144 daq_run (tgt, " PEDESTAL" , buffer, n_events, 100 );
121- lowend = get_adc_medians (buffer.get_buffer ());
145+
146+ for (int i_roc : tgt->roc_ids ()) {
147+ lowend[i_roc] = get_adc_medians (i_roc, tgt->getRocErxMapping (), buffer.get_buffer ());
148+ }
122149 }
123150
124151 pflib_log (info) << " sample collections done, deducing settings" ;
125- std::map<std::string, std::map<std::string, uint64_t >> settings;
126- for (int ch{0 }; ch < 72 ; ch++) {
127- std::string page{pflib::utility::string_format (" CH_%d" , ch)};
128- int i_link = ch / 36 ;
129- if (baseline.at (ch) < target.at (i_link)) {
130- pflib_log (debug) << " Channel " << ch
131- << " is below target, setting TRIM_INV" ;
132- double scale = static_cast <double >(target.at (i_link) - baseline.at (ch)) /
133- (highend.at (ch) - baseline.at (ch));
134- if (scale < 0 ) {
135- pflib_log (warn) << " Channel " << ch
136- << " is below target but increasing TRIM_INV made it "
137- " lower??? Skipping..." ;
138- continue ;
139- }
140- if (scale > 1 ) {
141- pflib_log (warn) << " Channel " << ch
142- << " is so far below target that we cannot increase "
143- " TRIM_INV enough."
144- << " Setting TRIM_INV to its maximum." ;
145- settings[page][" TRIM_INV" ] = 63 ;
146- continue ;
147- }
148- // scale is in [0,1]
149- double optim = scale * 63 ;
150- uint64_t val = static_cast <uint64_t >(optim);
151- pflib_log (trace) << " Scale " << scale << " giving optimal value of "
152- << optim << " which rounds to " << val;
153- settings[page][" TRIM_INV" ] = val;
154- } else {
155- double scale = static_cast <double >(baseline.at (ch) - target.at (i_link)) /
156- (baseline.at (ch) - lowend.at (ch));
157- if (scale < 0 ) {
158- pflib_log (warn) << " Channel " << ch
159- << " is above target but using SIGN_DAC=1 and "
160- " increasing DACB made it higher??? Skipping..." ;
161- continue ;
162- }
163- if (scale > 1 ) {
164- pflib_log (warn)
165- << " Channel " << ch
166- << " is so far above target that we cannot lower it enough."
167- << " Setting SIGN_DAC=1 and DACB to its maximum." ;
168- settings[page][" SIGN_DAC" ] = 1 ;
169- settings[page][" DACB" ] = 31 ;
170- continue ;
171- }
172- double optim = scale * 31 ;
173- uint64_t val = static_cast <uint64_t >(optim);
174- pflib_log (trace) << " Scale " << scale << " giving optimal value of "
175- << optim << " which rounds to " << val;
176- if (val == 0 ) {
177- pflib_log (debug)
178- << " Channel " << ch
179- << " is above target but too close to use DACB to lower, skipping" ;
180- } else {
152+ std::map<int , std::map<std::string, std::map<std::string, uint64_t >>> settings;
153+ for (int i_roc : tgt->roc_ids ()) {
154+ for (int ch{0 }; ch < 72 ; ch++) {
155+ std::string page{pflib::utility::string_format (" CH_%d" , ch)};
156+ int i_half = ch / 36 ;
157+ if (baseline[i_roc].at (ch) < target[i_roc].at (i_half)) {
181158 pflib_log (debug) << " Channel " << ch
182- << " is above target, setting SIGN_DAC=1 and DACB" ;
183- settings[page][" SIGN_DAC" ] = 1 ;
184- settings[page][" DACB" ] = val;
159+ << " is below target, setting TRIM_INV" ;
160+ double scale = static_cast <double >(target[i_roc].at (i_half) - baseline[i_roc].at (ch)) /
161+ (highend[i_roc].at (ch) - baseline[i_roc].at (ch));
162+ if (scale < 0 ) {
163+ pflib_log (warn) << " Channel " << ch
164+ << " is below target but increasing TRIM_INV made it "
165+ " lower??? Skipping..." ;
166+ continue ;
167+ }
168+ if (scale > 1 ) {
169+ pflib_log (warn) << " Channel " << ch
170+ << " is so far below target that we cannot increase "
171+ " TRIM_INV enough."
172+ << " Setting TRIM_INV to its maximum." ;
173+ settings[i_roc][page][" TRIM_INV" ] = 63 ;
174+ continue ;
175+ }
176+ // scale is in [0,1]
177+ double optim = scale * 63 ;
178+ uint64_t val = static_cast <uint64_t >(optim);
179+ pflib_log (trace) << " Scale " << scale << " giving optimal value of "
180+ << optim << " which rounds to " << val;
181+ settings[i_roc][page][" TRIM_INV" ] = val;
182+ } else {
183+ double scale = static_cast <double >(baseline[i_roc].at (ch) - target[i_roc].at (i_half)) /
184+ (baseline[i_roc].at (ch) - lowend[i_roc].at (ch));
185+ if (scale < 0 ) {
186+ pflib_log (warn) << " Channel " << ch
187+ << " is above target but using SIGN_DAC=1 and "
188+ " increasing DACB made it higher??? Skipping..." ;
189+ continue ;
190+ }
191+ if (scale > 1 ) {
192+ pflib_log (warn)
193+ << " Channel " << ch
194+ << " is so far above target that we cannot lower it enough."
195+ << " Setting SIGN_DAC=1 and DACB to its maximum." ;
196+ settings[i_roc][page][" SIGN_DAC" ] = 1 ;
197+ settings[i_roc][page][" DACB" ] = 31 ;
198+ continue ;
199+ }
200+ double optim = scale * 31 ;
201+ uint64_t val = static_cast <uint64_t >(optim);
202+ pflib_log (trace) << " Scale " << scale << " giving optimal value of "
203+ << optim << " which rounds to " << val;
204+ if (val == 0 ) {
205+ pflib_log (debug)
206+ << " Channel " << ch
207+ << " is above target but too close to use DACB to lower, skipping" ;
208+ } else {
209+ pflib_log (debug) << " Channel " << ch
210+ << " is above target, setting SIGN_DAC=1 and DACB" ;
211+ settings[i_roc][page][" SIGN_DAC" ] = 1 ;
212+ settings[i_roc][page][" DACB" ] = val;
213+ }
185214 }
186215 }
187216 }
0 commit comments