Skip to content

Single photon Spectrum event - #457

Draft
vbe9cs wants to merge 4 commits into
mainfrom
SPS
Draft

Single photon Spectrum event#457
vbe9cs wants to merge 4 commits into
mainfrom
SPS

Conversation

@vbe9cs

@vbe9cs vbe9cs commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

This has been our attempt at UVA to make a scan that is able to take data from a large amount of LED daq_runs (measuring over multiple bunch crossings and phase_ck values).

  • First the SPS_READOUT command takes lots of input values (LED_DAC, SiPM_DAC, BX, etc...) and applies them to the ROC and HDMI port of interest. Next it scans using a LED scan and writes the data to a CSV file
  • This CSV file is then interpreted and made into histograms with the SPS_histogram.py file (See pic below)
image - To run this correctly: before you run the SPS_READOUT command please find a correct TRIM_INV value to set the port to (my stratedgy is to take one of the values found by running LOCAL_PEDESTALS and then using it for all of them, but only really focusing on the channel that the TRIM_INV value corresponds to (Could be updated in the future), this is done to attempt to lower the spread of values). Next you run the SPS_READOUT command. The settings that we have been setting at uva with multiple ROCs attached to our backplane have been:
  1. 1000-10000 events per time point
  2. 22 as the Target bunch crossing
  3. Number of bunch crossing to scan over = 2
  4. SiPM_DAC = 3850
  5. LED_DAC = 3000
  6. Only doing the PHASE_CK value of 2 and no other values
  7. TRIM_INV of 9 (it works for one of the channels)
  8. Range of TRIM_INV values: 1 (used for DNL later)
  9. inputdac = 32 (guess)
  • Once you have taken a run go to the ana/LED directory and run "python3 SPS_histogram.py /full/path/" and it will produce the desired graphs
  • Please note: this is only a start, at UVA we have had very little success actually getting this to work with regards to getting a substantive spectrum for the photons interacting with the SiPM, there are many settings that we have not confirmed are correct. Most of these come from the CSM documentation that we could find and some previous experience in the LED_BIAS_SCAN settings. Any additional work on alternative settings would greatly be appreciated, but I feel that it is focus on what the correct value for inputdac is and what the biasing should be for this scan.
  • NOTE: this is partially incomplete and I have not added a functionality to add all of the data from a single run that are on different bunch crossings together in any way, so I believe that the function just records them as entries in the CSV file, need to update this.

@tomeichlersmith tomeichlersmith left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good! Thank you

I have a lot of nit-picky updates, but nothing too serious that changes the overall logic or intention.

Comment thread ana/LED/SPS_histogram.py
Comment on lines +44 to +50
bins = np.arange(min_adc - 0.5, max_adc + 1.5, 1)

counts, edges = np.histogram(data_hist, bins)
errors = np.sqrt(counts)
centers = (edges[:-1] + edges[1:]) / 2
hep.histplot((counts, edges), ax=ax, histtype='step', density=False, label=labels)
ax.errorbar(centers, counts, yerr=errors, fmt='.', capsize=2, markersize=3)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mechanic of filling histograms and plotting them with error bars is also accomplished by the hist package https://hist.readthedocs.io/en/latest/
I would suggest using it because it makes your code simpler and it has sensible defaults for error calculations and plotting styles.

Comment on lines +26 to +30
auto hcalbp = dynamic_cast<pflib::HcalTarget*>(tgt);
if (!hcalbp) {
PFEXCEPTION_RAISE("BadTarget",
"led_bias_scan only available for Hcal targets");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to the beginning of the function so nothing is run if its the wrong target type.

Comment thread app/tool/tasks/tasks.cxx
->line("LED_BIAS_SCAN", "Sweeps SiPM and LED DACs", led_bias_scan)
->line("SPS_READOUT",
"Take data of a photospectrum on one bunch crossing",
sps_readout);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can also prevent SPS_READOUT from being display for non-Hcal targets

Suggested change
sps_readout);
sps_readout, ONLY_HCAL);

which we should probably add to the LED_BIAS_SCAN as well

Comment on lines +8 to +13
* Used to scan different SiPM or LED DAC values/biases.
* Both can either be varied over a range, or kept constant if the same value is
* entered for the start and stop value. One can choose how many ports have CMBs
* connected An LED flash on one CMB flashes into four HGCROC channels
* simultaneously, thus the pulses of all four respective channels are recorded
* in the csv file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a copy of led_bias_scan's description? Please update

Comment thread app/tool/tasks/SPS_readout.cxx Outdated
Comment on lines +75 to +76
nlohmann::ordered_json header;
f << std::boolalpha << "# " << header << '\n'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This JSON header is useful for including extra metadata about the run.
Things I would suggest including:

  • ROC/Channel that is being studied
  • target bx
  • other parameters that are constant for the run but different from the defaults

Comment on lines +111 to +112
.add(calib_page, "INPUTDAC",
32) // No idea what this should be (MAXES out at 63)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add more comments describing what these parameters are trying to do. This is more than just "turning on charge injections" as stated in your comment above.

Add comments in the line above the parameter just to make the formatting easier

Suggested change
.add(calib_page, "INPUTDAC",
32) // No idea what this should be (MAXES out at 63)
// No idea what this should be (maxes out at 63)
.add(calib_page, "INPUTDAC", 32)

Comment on lines +147 to +148
tgt->fc().fc_setup_led(tgt_bx);
pflib_log(info) << " Target BX = " << tgt_bx << "\n";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, you change the led bx offset here but do not revert it back to the value it had before. Please add the "revert" mechanic so the led bx offset is only ever permanently updated when the user intends to update it.

int tgt_bx =
pftool::readline_int("Target BX? (~22 should be BX = 4) ", start_led);
int len_bx = pftool::readline_int("Number of BX to scan over? ", 2);
tgt->fc().setL1AperROR(len_bx);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides sending a burst of extra L1A per ROR, we also need to inform the data collection side that it should expect multiple samples.

pflib/app/tool/daq.cxx

Lines 112 to 114 in f856638

daq.setup(econid, samples, soi);
if (pft->trig()) pft->trig()->set_l1a_per_ror(samples);
pft->fc().setL1AperROR(samples);

It might be easier to just not allow users to change the number of BX being collected here and instruct them to use daq.setup.config if they want to use multi-sampling.

Comment on lines +152 to +159
// auto data = buffer.get_buffer();
// auto mapping = tgt->getRocErxMapping();
// auto [i_erx, i_ch] = mapping.toErxChannel(i_roc, 17);
// for (std::size_t i{0}; i < data.size(); i++) {
// for (int j = 0; j < nr_bx; j++) {
// adcs[j].push_back(data[i].samples.at(j).channel(i_erx, i_ch).adc());
//}
//}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove code that is now commented-out and not in use.

Suggested change
// auto data = buffer.get_buffer();
// auto mapping = tgt->getRocErxMapping();
// auto [i_erx, i_ch] = mapping.toErxChannel(i_roc, 17);
// for (std::size_t i{0}; i < data.size(); i++) {
// for (int j = 0; j < nr_bx; j++) {
// adcs[j].push_back(data[i].samples.at(j).channel(i_erx, i_ch).adc());
//}
//}

@haseckew

Copy link
Copy Markdown
Contributor

just adding my updates to the SPS script and plotting (more for Cristina's use); they are untested so Tom you don't really need to look at them right now, will merge again once tested


auto test_param_handle = test_param_builder.apply();

<<<<<<< Updated upstream

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These merge conflicts arose because

  1. You opened this PR which triggered an auto-formatting commit to be pushed
  2. You also edited those same files

The good news is that the auto-formatting can be re-run pretty easily, so if you want to avoid these merge conflicts in the future you can force push your commits and delete the auto-formatting commit. You can also do formatting locally or just remember to git pull before you make more changes on the branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants