Giter Club home page Giter Club logo

wfsim's Introduction

wfsim's People

Contributors

dachengx avatar dependabot[bot] avatar ershockley avatar faroutylq avatar ftoschi avatar giovannivolta avatar henningse avatar jelleaalbers avatar jmosbacher avatar joranangevaare avatar josephjhowlett avatar jyangqi00 avatar karamelih avatar l-althueser avatar masatoshikobayashi avatar mzks avatar pavelkavrigin avatar petergaemers avatar ramirezdiego avatar shenyangshi avatar sophiafarrell avatar terliuk avatar zhut19 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wfsim's Issues

Split and refactor core.py

Our core.py is unreasonably long and very hard to navigate. Does it make sense to split it into separate files corresponding to pulse class, S1, S2 etc? I think it will hugely improve development and testing of our MC.

AP file

if config['enable_pmt_afterpulses']:

Hi all,
the AP file in 'private_nt_aux_files/sim_files/' is a json file, and straxen.get_resource is trying to open a pkl. Is it on purpose?

I am trying to make simulation using some instructuions. I am then defing the context liket this:

conf = straxen.contexts.xnt_common_config
conf['gain_model'] = ('to_pe_per_run', '/home/gvolta/XENONnT/private_nt_aux_files/sim_files/to_pe_nt.npy')
st   = strax.Context(storage='/dali/lgrandi/giovo/XENONnT/WFsim_data/strax_data/',
                     config=dict(detector='XENONnT',
                                 fax_config='/home/gvolta/XENONnT/private_nt_aux_files/sim_files/fax_config_nt_low_field.json',
                                 fax_file=f'/home/gvolta/XENONnT/Analysis/WFSim/instructions/{run_id}.csv',
                                 **conf,
                                 fax_config_override={
                                     'electron_extraction_yield': 1,  # temp fix
                                     's2_secondary_sc_gain': 31.5 / 0.09091864874478181,  # temp fix
                                     'pmt_ap_t_modifier': 0,
                                     'url_base': '/home/gvolta/XENONnT/private_nt_aux_files/sim_files/',
                                     #'photon_area_distribution': 'XENONnT_spe_distributions_20210305.csv',
                                     #'photon_ap_cdfs':'XENONnT_pmt_afterpulse_config_012605.json.gz',
                                     'enable_pmt_afterpulses':False,
                                 }),
                     **straxen.contexts.common_opts)
st.register(wfsim.RawRecordsFromFaxNT)

enable_pmt_afterpulses must be False otherwise I got an error

Improper handling of empty chunk

From https://github.com/XENONnT/WFSim/blob/master/wfsim/strax_interface.py#L969, if a chunk has empty data (occurs when chunk_size or event_rate is set too small), WFSim will create chunks with start time and end time to be zeros. This will cause an exception when strax checks the continuity of chunks, like:

Simulating Raw Records:  15%|█▌        | 14/93 [00:11<01:00,  1.31it/s]Traceback (most recent call last):
  File "/home/mhliu0001/ambe_simulation/./mc_chain/run_wfsim.py", line 238, in <module>
    st.make(args.run_id, 'raw_records')
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/context.py", line 1426, in make
    for _ in self.get_iter(run_ids[0], targets,
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/context.py", line 1336, in get_iter
    generator.throw(e)
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/processor.py", line 302, in iter
    raise exc.with_traceback(traceback)
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/processor.py", line 255, in iter
    yield from final_generator
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/mailbox.py", line 447, in _read
    self.kill_from_exception(e)
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/mailbox.py", line 213, in kill_from_exception
    raise e
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/mailbox.py", line 444, in _read
    yield res
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/context.py", line 1307, in get_iter
    for n_chunks, result in enumerate(strax.continuity_check(generator), 1):
  File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.9/site-packages/strax/chunk.py", line 318, in continuity_check
    raise ValueError("Data is not continuous. "
ValueError: Data is not continuous. Chunk [mc_1.raw_records: 0sec 0 ns - 0sec 0 ns, 0 items, -1.0 MB/s] should have started at 215099900000

Quanta from nestpy called twice

I just noticed in this tutorial that the quanta generation is done twice on the yields. The reason why this is an issue is that in one call, the total quanta is conserved, but if you call GetQuanta twice, there's no telling what n_e + n_photons will add up to be and no validity test that they will be equal to the total quanta number. I am unsure if this is replicated throughout the code, in which case it will require updating as soon as possible.

Here's how it looks now in the tutorial:

quanta.append(nc.GetQuanta(y, density).photons)
quanta.append(nc.GetQuanta(y, density).electrons)

And here is how you want it to look:

q = nc.GetQuanta(y, density) # or whatever you want to call it
quanta.append(q.photons)
quanta.append(q.electrons)

Let me know if I am missing something or if you need more clarifications! Thanks!

General comments

If you putting it on PyPI, I'd keep the HISTORY file up to date because otherwise the PyPI page when you are looking for the package only shows really outdated irrelevant info.

drift_time_mean consistency definition

In core/s2.py, the definition of drift_mean_time includes the drift_time_gate, but it is used to evaluate parameters like the diffusion, where the gate transit time should be neglected as in this conditions the electric field is very different and the diffusion constant is very different. In #235, the drift_mean_time in s2_pattern_map_diffuse does not include the transit time by the gate:

drift_time_mean = - z / drift_velocity_liquid

Even though the effect should be overall small, wouldn't it be better to use the drift time without the gate transit to evaluate the diffusion parameters and then add the final gate transit time in order to evaluate the time difference between S1 and S2?

Instructions type of pulse S1/S2 vs. 1/2

Whereas the instructions of the WFsim takes the type of peak as a string (see e.g. below), this is specified as an integer in peaks_basics (https://straxen.readthedocs.io/en/latest/reference/datastructure.html#peak-classification. The line in the WFsim:

instruction_dtype = [('event_number', np.int), ('type', '<U2'), ('t', np.int),

Would it make sense to alter the Wfsim to also take an integer specification of the type of peak?

Use per pmt DPE probability

The DPE probability is shown to be different for each PMTs, and systematically larger for the bottom array.

Turned off PMTs with data-driven LCE

When we produce simulations, we throw PMT hits according to the LCE of individual PMTs and then "zero" turned off PMTs with gain value. This apporach is totally valid as long as we have simulation-driven maps. But the moment when we turn to data-driven maps, the S1 LCE already includes not working PMTs by definition, but pattern maps do not. This can cause area/AFT/etc biases, so we have to think how to treat it.

Corresponding PR: #230

P.S. This issue was first accidentally put in private repo

No interactions found -> crash of RawRecordsFromMcChain

Currently, when we use RawRecordsFromMcChain plugin, if there are no interactions found by epix, it will cause a crash with this error:

        Traceback (most recent call last):
          File "run_wfsim.py", line 120, in <module>
            st.make(args.run_id, 'raw_records')
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/strax/context.py", line 1411, in make
            for _ in self.get_iter(run_ids[0], targets,
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/strax/context.py", line 1263, in get_iter
            components = self.get_components(run_id,
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/strax/context.py", line 1024, in get_components
            d.setup()
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/wfsim/strax_interface.py", line 556, in setup
            self.get_instructions()
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/wfsim/strax_interface.py", line 809, in get_instructions
            self.set_timing()
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/wfsim/strax_interface.py", line 819, in set_timing
            % (self.config['entry_stop'], np.min(self.g4id), np.max(self.g4id)))
          File "<__array_function__ internals>", line 180, in amin
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 2916, in amin
            return _wrapreduction(a, np.minimum, 'min', axis, None, out,
          File "/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 86, in _wrapreduction
            return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
        ValueError: zero-size array to reduction operation minimum which has no identity

This exception must be handled, and it would also make sense to check beforehand if there're any interactions to process or not. As for now, WFSim crashes, and it triggers useless job resubmissions if we use mc_chain.

Example Kr notebook

The gain calculation bug from #161 and solved in #164, made us realized the importance of having a sanity check notebook. One idea is to simulate Kr events and do simple checks like S1 and S2 area distributions, etc.

S2 Photon timing downsampled for large time in instruction

When taking a instruction with huge timestamp (also in int64), you will have weird S2 waveforms, where the photons timing are downsampled. More discussion here. It is true to all S2s simulated.

Example for simulation using big time instruction

import cutax
st = cutax.xenonnt_sim_base(output_folder='/scratch/midway3/yuanlq/wfsim')
st.set_config({"fax_file" : "/project/lgrandi/yuanlq/wimp/s2sim/021952-9-se-all-20.csv"}) # feel free to check
se_peaklets = st.get_array('021952_se', 'peaklets')

for p in se_peaklets[:100]:
    if p['dt']==10:
        plt.plot(p['data'])
plt.xlabel('Sample [10ns]')

image

Example for simulation using small time instruction (what people usually do)

st = cutax.xenonnt_sim_base(output_folder='/scratch/midway3/yuanlq/wfsim')
st.set_config({"fax_file" : "/project/lgrandi/yuanlq/wimp/s2sim/jy_se_f6191.csv"}) # the first 100 rows of /project/lgrandi/jyangqi/se_sim_stuff/se_f6191.csv

se_peaklets = st.get_array('se_f6191', 'peaklets')
for p in se_peaklets[:100]:
    if p['dt']==10:
        plt.plot(p['data'])
plt.xlabel('Sample [10ns]')

image

The issue is suspected to happen when int64 were casted into float.

Add inverse field distortion for nT

Issue to not lose track of this open point. The approach now for simulations is of course to not apply any FDC, since there's no distortion to correct for. But this can be reversed.

Inspiration can be taken from these lines, used for 1T (thanks @petergaemers for sharing):

WFSim/wfsim/core.py

Lines 708 to 731 in b204045

def inverse_field_distortion(x, y, z, resource):
"""For 1T the pattern map is a data driven one so we need to reverse engineer field distortion
into the simulated positions
:param x: 1d array of float
:param y: 1d array of float
:param z: 1d array of float
:param resource: instance of resource class
returns z: 1d array, postions 2d array
"""
positions = np.array([x, y, z]).T
for i_iter in range(6): # 6 iterations seems to work
dr = resource.fdc_3d(positions)
if i_iter > 0:
dr = 0.5 * dr + 0.5 * dr_pre # Average between iter
dr_pre = dr
r_obs = np.sqrt(x**2 + y**2) - dr
x_obs = x * r_obs / (r_obs + dr)
y_obs = y * r_obs / (r_obs + dr)
z_obs = - np.sqrt(z**2 + dr**2)
positions = np.array([x_obs, y_obs, z_obs]).T
positions = np.array([x_obs, y_obs]).T
return z_obs, positions

No 1T full-chain compatibility

The 1T compatibility was skipped in the full-chain WFSim classes development: #103
See this class

class RawRecordsFromFaxEpix(RawRecordsFromFaxNT):

only called when the nT simulations context is active.

This is not a big deal right now. However, MC and epix are 1T-compatible, and the mc_chain scripts were written so that 1T full-chain simulations can also be ran (maybe a nice option for validation?). In addition, WFSim itself was already used for 1T and is compatible, so only a small refactoring of these classes would be needed to enable 1T full-chain simulations. I cc @petergaemers to comment if the latter statement is incorrect and lots of work would be required here (maybe you think it makes sense that, for 1T, we run epix separately and apply the time shifts directly in there?); and I cc the ACs (@jpienaar13, @kdund, @skazama) in case they want to share their thoughts.

In any case I'm not strongly concerned about this, but just wanted to make people aware.

Start/stop time and true area in truth info

Currently WFsim's 'truth info' just repeats the instructions. For testing the processor performance, we instead need for each peak: its actual simulated location in time (e.g. start/stop or left/right) as well as the true number of simulated photons (without afterpulses / single electrons).

See also the truth output production in fax: https://github.com/XENON1T/pax/blob/master/pax/plugins/io/WaveformSimulator.py#L70 and https://github.com/XENON1T/XeAnalysisScripts/blob/master/PeakFinderTest/match_peaks.py, which we used for simulator-based processor tests in XENON1T.

Issue Importing WFSim

If I run these statements:

git clone https://github.com/XENONnT/WFSim
pip install -e ./WFSim
import WFSim

And then, try this:

st = strax.Context(
        storage=strax.DataDirectory('./strax_data'),
        register=wfsim.RawRecordsFromFax1T,
        config=dict(detector='XENON1T',
                    fax_config='https://raw.githubusercontent.com/XENONnT/'
                               'strax_auxiliary_files/master/fax_files/fax_config_1t.json',
                    **straxen.contexts.x1t_common_config,),
        **straxen.contexts.common_opts)

I end up with the error:
NameError: name 'wfsim' is not defined

FullChain and WFSim MultiProcessing

Issue:

WFSim is computationally the heaviest part in our full chain simulation. Therefore, it would be nice if we could utilize strax's Mailbox-System for parallel processing. However, this can be a big hurtle since we have to switch from a eventid based ordering scheme used by GEANT4 to a time based one which is used by strax/en (This issue has to be overcome anyhow since we want to use strax/straxen in our analyses.). Hence, in order to use multiprocessing with WFSim, EPIX has to provide non-overlapping, time sorted and time chunked data. I discussed this idea already with @HenningSE, @petergaemers and @ramirezdiego and would like to use this issue to present the idea in more detail. The changes should be minior, mainly in EPIX and fast to be implemented. Further, I would like to ask people to comment in case I overlooked any obstacles.

Proposal:

The main concept is sketch in the subsequent figure.

example

Step 1. GEANT4:
GEANT4 is the starting point of our full chain simulation and computationally the second heaviest part of the entire chain. In my current proposal we would exploit the already recently implemented features like a continuous running eventid and use multiple jobs running in parallel to simulate our data. Each job writes its results into a file in a single directory. The filename would have to follow some convention we have to agree on e.g. like sim_runid_000001.root....

Step 2. EPIXReader:
After GEANT4 we use EPIX to define interactions and timestamps which are passed as instructions to WFSim. In previous proposals for our full-chain-simulation approach, EPIX runs together with GEANT4 in independent parallel jobs. However, I think we should run it as a single serial job which loops over all created GEANT4 files.

EPIX poses our best chance to transform our data from an eventid based to a time based ordering scheme. It is very fast compared to the other tools mentioned. It takes about ~2-3 minutes for 15k neutrons events. Hence, it would not create a new bottleneck if it is not parallelized. And, we already define timestamps in EPIX which are passed as instructions to WFSim.

The changes would look like the following: We move EPIX into a strax-plugin which has the task to provide well defined, non-overlapping chunks of data. This is similar to the DAQReader for regular data-taking ("EPIXReader"). This can only be ensured if EPIXReader loops over our data in a serial way and postpone events (or S2s of an event) into a future chunk if needed. The chunks can be created in two different ways. Either based on an event rate or well separated events for a clean simulation. Further should each chunk always contain about 5k events to ensure a not too large I/O-overhead. Depending on the user specified rate or creation method the chunk size may vary from simulation to simulation, but this should not be of any problem.

However, there are two obstacle which we have to overcome. On the other hand this issue would occur the either way. Due to after pulse simulation in WFSim, e.g. photo-ionization signals, signals can be produced far beyond the chunk boundaries if computed in a naive way. Hence I would propose, that the chunk-endtime is always computed such that we can accommodated afterpulses up to a max delay of 4 drift lengths after the original interaction (can also either reduce or increase this number if needed). Afterpulses beyond that time are truncated.
For the very same reason it may be required in a few cases to extend the chunk-boundary a bit. This introduces a small but negligible error on the event rate. E.g. if we have a source with a rate of 50 Bq we have a chunksize of 100 s. If we are unlucky and the last S2 is placed at a time of 100s we have to extend the chunk by 4 x max drift time.

Step 3.:
WFSim would remain more or less unchanged, I think. We just need to add the 4 x max drift truncation and switch to multi-processing.

Advantages:

  • Single eventid per simulation, also simplifies the gain-handling
  • Robust rate and pile-up simulations
  • Easier and more robust tracking of settings via strax.Options.
  • No overlapping pulses after WFSim
  • Huge speed increase for WFSim

Disdvantage:

  • Not sure if this is one, but nVETO data has also to run through both plugins. Otherwise it will become a mess.

Peter started the transition to a strax-plugin already: XENONnT/epix#7, but we have to make the changes on the timestamp creation first.

ToDo:

In the following I list the required changes. Step 2. changes can be done at a later time once we verified the full chain simulation is working.

Epix:

  • Define FAX-config via strax.Option and get drift time (step 2)
  • Change event time computation
  • Agree on MC run-id structure
  • Finish plugin

WFSim:

  • Define Fax config via strax.Option (step 2)
  • Depend on EPIXReader
  • Truncate afterpulses, raise if regular S1/S2 gets truncated

Both:

  • Add nVETO support to both tools. (step 2)

S1/S2 grouping in truth

Currently the information written to the truth output of WFSim is reduced:

All S1s within 100 ns separation are merged:

np.where(np.diff(instb_time[ibqs[mask]]) > 100)[0] + 1)

All S2s within 2 mm separation are merged:

np.where(np.diff(instb_time[ibqs[mask]]) > int(0.2 / v))[0] + 1)

As a result, the truth cannot be used for any analysis which requires a knowledge of true multi-scatters in the instructions since this information is lost if the interactions happen close to each other. The most simple fix would be just to change these thresholds, e.g. 100 ns to 0.1 ns, 2 mm to 1 um. In case if we want to keep a possibility to reduce the size of the truth output, we will need to add some flag to the configuration to specify whether we want to merge instructions in the truth or not.

Seeding numba functions

There are a few numba'd functions which use random numbers like luminescene timings and the add_noise.
When setting a seed for the random number generator this is NOT applied to the numba'd random generator

So we need to fix this. This shouldn't be hard, something like pass the seed as a argument to the relevant functions. But make sure to only seed once

Something like this:
numba/numba#3249

How to implement PMT QE for nVeto

I create very dirty, broken implementation to add PMT QE for nVeto PMTs. (branch nveto_pmt_qe).
The implementation is bad, and it generates errors.

In my naive prediction, only what we have to do is dropping channels and timings after reading Geant4 input, but I may care about ins (instruction) at the same time.
Could you please give me a hint to implement?

For your information,
For nVeto PMTs, I will add static number of QE(*CE) for all PMTs because there are no QE specification sheet for all PMTs. (Half PMTs have measured values.)

Mismatch in event_number

As for now, event_number in truth (i.e. the numbers generated by epix) does not correspond to event_number in the event-level data generated by straxen, e.g. event_info. The latter one is generated here:

https://github.com/XENONnT/straxen/blob/f6e0966e3d78c7e663f7cd4caca2eff32b12643e/straxen/plugins/event_processing.py#L127

The result is very misleading since one might select certain events via event_info (testing cuts etc.) and then look for the origin of these events in the truth using event_number. The result will be incorrect.

Here's an example notebook which demonstrates this issue:
/dali/lgrandi/pkavrigin/2022-07-18_wfsim_test/2022-07-18_wfsim_test.ipynb

Possible solutions:

  • Remove event_number from truth. We can use g4id for event grouping, if needed. This way we can at least make sure that nobody tries to match truth to event-level output in a wrong way.
  • Propagate event_number from truth to event-level output. I do not see a way to do it without modifying straxen, so this is probably not a good idea.
  • Match events in event-level output to truth using time. It is feasible (and it is the only way to match them right now) but it's not clear if we can add it as some post-processing stage to wfsim.

@ramirezdiego @terliuk @petergaemers @shenyangshi - Any ideas?

KeyError: 'No plugin class registered that provides peak_classification'

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-12-0ca034f9b93f> in <module>
      3 
      4 records = st.get_array(run_id,'records')
----> 5 peaks = st.get_array(run_id, ['peaks','peak_classification'])
      6 data = st.get_df(run_id, 'event_info')
      7 

/dali/lgrandi/strax/strax/strax/context.py in get_array(self, run_id, targets, save, max_workers, **kwargs)
    912             results = list(self.get_iter(run_ids[0], targets,
    913                                          save=save, max_workers=max_workers,
--> 914                                          **kwargs))
    915         if len(results):
    916             return np.concatenate(results)

/dali/lgrandi/strax/strax/strax/context.py in get_iter(self, run_id, targets, save, max_workers, time_range, seconds_range, time_within, time_selection, selection_str, **kwargs)
    793         # to merge the results automatically
    794         if isinstance(targets, (list, tuple)) and len(targets) > 1:
--> 795             plugins = self._get_plugins(targets=targets, run_id=run_id)
    796             if len(set(plugins[d].data_kind for d in targets)) == 1:
    797                 temp_name = ('_temp_'

/dali/lgrandi/strax/strax/strax/context.py in _get_plugins(self, targets, run_id)
    413         plugins = collections.defaultdict(get_plugin)
    414         for t in targets:
--> 415             p = get_plugin(t)
    416             # This assignment is actually unnecessary due to defaultdict,
    417             # but just for clarity:

/dali/lgrandi/strax/strax/strax/context.py in get_plugin(d)
    359 
    360             if d not in self._plugin_class_registry:
--> 361                 raise KeyError(f"No plugin class registered that provides {d}")
    362 
    363             p = self._plugin_class_registry[d]()

KeyError: 'No plugin class registered that provides peak_classification'

nVeto pulses haven't made following Geant4 file

I found among timing check that WFSim doesn't make nVeto pulse following Geant4 file.
Events which have no nVeto hits in G4, have records_nv and truth_nv

I guess that nVeto events are shifted in somewhere...

return channels[hit_mask], timings[hit_mask], np.array(amplitudes, int)

At this line, G4 array is flatten. There may be a bug in chopping the events after that line.
We need to check them carefully.

Rest information I investigated is there.

I used this file and tried to make pulses with very low rate.
/dali/lgrandi/xenonnt/simulations/testing_epix_wfsim/tpc_and_nveto_cryoneutrons_200.root
python v3.7.9 (default, Dec 15 2020, 15:48:53) [Clang 11.0.0 ]
strax v0.16.0 /Users/mzks/.pyenv/versions/3.7.9/lib/python3.7/site-packages/strax
straxen v0.19.2 /Users/mzks/xenon/straxen/straxen
wfsim version:0.5.6
epix version:0.1.1

Scripts:

import strax, straxen, wfsim, epix, nestpy
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import uproot

st = straxen.contexts.xenonnt_simulation()
st.register(wfsim.RawRecordsFromMcChain)
epix_config = {
    'cut_by_eventid': True,         # means that entry_start and entry_stop refer to the original G4 event id
    'debug': True,                  # print runtime outputs
    'source_rate': 0,               # do not alter G4 time of events, because this will be done in WFSim
    'micro_separation_time': 10.,   # ns; default epix separation for clustering decision
    'max_delay': 1e7                # ns; default epix cut for long events (time wrt to first interaction in TPC)
}
epix_config['detector_config_override'] = None
epix_config['micro_separation'] = 0.05
epix_config['tag_cluster_by'] = 'time'

st.set_config(dict(
    detector='XENONnT',
    #fax_file='/Users/mzks/xenon/mc/mc/build/bin/laser_test10_10000.root',
    fax_file='/Users/mzks/xenon/WFSim/bench/tpc_and_nveto_cryoneutrons_200.root',
    event_rate=1.,
    chunk_size=5.,
    entry_start=0,
    #entry_stop=20,
    #fax_config='fax_config_nt_sr0_v0.json',
    fax_config='fax_config_nt_design.json',
    fax_config_override=dict(url_base='https://raw.githubusercontent.com/XENONnT/private_nt_aux_files/master/sim_files',
                             enable_electron_afterpulses=False),
    epix_config=epix_config,
    targets=('tpc',))
)
st.set_config(dict(
    neutron_veto=True,
    fax_config_nveto='fax_config_nt_nveto.json',
    fax_config_override_nveto=dict(enable_noise=False,
                                   enable_pmt_afterpulses=False,
                                   enable_electron_afterpulses=False,
                                   photon_area_distribution='/Users/mzks/xenon/WFSim/bench/private_nt_aux_files/sim_files/XENONnT_spe_distributions_nveto_20210722.txt',
                                   pmt_transit_time_mean=46.0),
    targets=('tpc', 'nveto',),
))

run_id = 'timing_check_01'
rr = st.get_array(run_id, 'raw_records', progress_bar=False)
truth = st.get_array(run_id, 'truth', progress_bar=False)
rr_nv = st.get_array(run_id, 'raw_records_nv', progress_bar=False)
truth_nv = st.get_array(run_id, 'truth_nv', progress_bar=False)

Example:

In Original Geant4 file, event 11, g4_pmthitID[11] have no available ID for nVeto .
[106, 137, 314, 255, ... 276, 489, 438]
All of them are not nVeto ID (2000--2199)
But some records_nv have been observed.

S2 reconstruction bias when using noise (enable_noise)

The S2 reconstruction bias seems to be altered by the addition of noise. When using

st.set_config(dict(fax_config_override=dict( s2_luminescence_model='simple',enable_noise=1,)))

, the bias for Ar37-like S2s is in the order of 7%. When enable_noise=0, it is (within statistics) in the order of 0%.
I then re-ran the simulation with slightly higher energies (31.5 keV for Kr83m-like events (no double-S2 though)) and the same effect shows up, although with the bias magnitude being reduced to 2-3%. This points at a constant offset in the area reconstruction, like a wrong baseline. A couple plots showing the effect for Ar37-like.

image
image

I will keep digging and update if I find anything.

AssertionError - Outside the TPC

@terliuk @ramirezdiego : The way the interaction positions from epix instructions are checked sometimes leads to an assertion error even though the interactions are within the TPC:

assert np.all(self.instructions['x']**2 + self.instructions['y']**2 < self.config['tpc_radius']**2), \

assert np.all(self.instructions_epix['x']**2 + self.instructions_epix['y']**2 <

Here's one the files which led to a crash of WFSim with AssertionError during mc_chain run:
/dali/lgrandi/pkavrigin/2022-06-13_WFSim_XYAssertionError/nT_mc_th228_aa_00188.root

These are the corresponding X and Y positions from epix:
/dali/lgrandi/pkavrigin/2022-06-13_WFSim_XYAssertionError/nT_mc_th228_aa_00188.X.npy
/dali/lgrandi/pkavrigin/2022-06-13_WFSim_XYAssertionError/nT_mc_th228_aa_00188.Y.npy

The issue can be reproduced with this notebook:

/dali/lgrandi/pkavrigin/2022-06-13_WFSim_XYAssertionError/2022-06-13_WFSim_XYAssertionError.ipynb

This is apparently a floating-point precision issue.

entry start/stop in McChainSimulator

What I truly want is to submit review comments to #103, but this would be a bit messy, since it is already merged, so I'll push here the changes we agree on: #125

  • First comment/request for @petergaemers: could you please resolve the open conversations in PR #103? I have some comments which I am not sure are repeated.

I want to first revisit the discussion on these arguments, which are always required for running the chain:

'entry_start':self.context.config['event_start'],
'entry_stop':self.context.config['event_stop'],

  • For example, in this function we use event_start and event_stop to calculate the rate

    def set_timing(self,):
    """Set timing information in such a way to synchronize instructions for the TPC and nVeto"""
    logging.info("Setting timings")
    #Rate in ns^-1
    rate = self.context.config['event_rate']/wfsim.units.s
    start = self.context.config['event_start']
    stop = self.context.config['event_stop']
    timings= np.random.uniform(start/rate,stop/rate,stop-start).astype(np.int64)
    timings.sort()

    If event_stop is equal to -1 (default), the code searches for the maximum G4 event id with this function, and assigns it to event_stop (by the way, I don't understand why the two last lines are needed):
    def _set_max(self,):
    """If no event_stop is specified set it to the maximum (-1=do all events)"""
    if self.context.config['event_stop']==-1:
    self.context.set_config(dict(event_stop=\
    np.max(self.instructions_epix['g4id'][-1],self.instructions_nveto['g4id'][-1])+1))
    else:
    pass

    I think this is not correct, since the last G4 id does not necessarily correspond to the last event simulated, which is the number that we should use to distribute the source rate.

  • Related to this, this function is only useful if we envision to decouple single ROOT files into multiple smaller ones, correct?

    def _instructions_from_epix_cut(self,):
    """Cut away events not within event_start & event_stop"""
    mask=(self.instructions_epix['g4id']<self.context.config['event_stop'])&\
    (self.instructions_epix['g4id']>=self.context.config['event_start'])
    self.instructions_epix = self.instructions_epix[mask]

    This function is redundant with the job epix already does, if you these two arguments always as epix config. Just to be clear: the default rate we want for epix in the mc_chain is 0, correct (i.e., no time correction applied in epix)?

S1/S2 pattern coordinates

I am trying to produce S2 patterns for position reconstruction with CNNs and have discovered that patterns do not correspond to generated positions. It looks like X and Y axis are flipped somewhere (alternatively, rotated+mirrored). I also checked it with S1 and they seem to have the same issue.

Here area couple of examples:
S2 signal:
S2_wfsim_XY_000003
S2_wfsim_XY_000008
S1 signal (produced just below the surface):
S1_wfsim_XY_000001
S1_wfsim_XY_000006
And for S1 near the bottom array:
S1_wfsim_bottom_XY_000002

Bug in complex deexcitation model

With the latest change to move from recoil type string to numbers there was a bug introduced. The check of the input has not been updated:

WFSim/wfsim/core.py

Lines 328 to 332 in 26eabfd

try:
self._photon_timings = np.append(self._photon_timings,
t + getattr(self, recoil_type.lower())(n_photons))
except AttributeError:
raise AttributeError('Recoil type must be ER, NR, alpha or LED, not %s' % recoil_type)

NaNs in t_last_photon

The truth table generated by WFSim occasionally produces NaN values in t_last_photon despite the fact that the instructions seem to indicate that the event should be detectable. The following event is an example of this:

event_number,type,time,x,y,z,amp,recoil,e_dep,g4id,vol_id,local_field,n_excitons,x_pri,y_pri,z_pri
140,1,1646832231842000000,-64.71233,9.902024,-133.29727,143,7,3.4371514,0,0,22.369154340346643,6,0.0,0.0,0.0
140,2,1646832231842000000,-64.71233,9.902024,-133.29727,103,7,3.4371514,0,0,22.369154340346643,6,0.0,0.0,0.0

Single electron gain

Currently the single electron gain much too low.
Instead of being around 40 photons per electron we currently make about 6

This is related to the normalization of the s2 pattern maps not being normalized

Match straxen config with fax_config in certain parameters.

Currently, set fax_config options are not propagated to straxen and event processing. While it might be useful to a certain extent, for some parameters such as the drift_velocity_liquid (electron_drift_velocity in straxen), it leads to a general misreconstruction of events.

  • Example: mono-energetic ER 30 kev
Not setting the straxen parameter manually. After changing straxen context config with electron_drift_velocity=("electron_drift_velocity_constant", v_drift, False)

Overlapping in raw_records

I was trying to run WFSim with instructions generated by EPIX. When trying to get the records with strax I get the following error:
ValueError: Bad data! In channel 165, a pulse starts at -440, BEFORE the previous pulse in that same channel ended (at 0)
The channel number changes randomly when rerunning the code multiple times. The WFSim version is 0.0.6.

How to reproduce the error

First I created the WFSim instructions with EPIX:

python3 bin/run_epix.py --InputFile /dali/lgrandi/xenonnt/simulations/nr_materials/mc_v3.0.0/noveto/XENONnT_BellPlate_neutron_50000-001.root --MicroSeparation 0.03 --TagClusterBy energy --Efield /dali/lgrandi/xenonnt/simulations/fieldMapMC.txt --EntryStop 1000  --OutputPath ./

You can also skip the EPIX step when using the instructions I already created. They can be found here:

/dali/lgrandi/hschulze/instructions_for_wfsim/nVETO_AmBe_neutrons_top_uring_2_wfim_instructions
/dali/lgrandi/hschulze/instructions_for_wfsim/XENONnT_BellPlate_neutron_50000-001_wfim_instructions

Next, set the config for WFSim:

st = straxen.contexts.xenonnt_simulation()
run_id = '1'
st.set_config(dict(fax_file=instructions_file))

and simulate the raw_records:

# Remove any previously simulated data, if such exists
!rm -r strax_data
rr = st.get_array(run_id,'raw_records')

With the next line I try to get the records:

records = st.get_array(run_id,'records')

At this stage I get the error message given above. As additional check I had a look into the raw_recordsas proposed by @WenzDaniel:

for ch in range(494):
    rc = rr[rr['channel'] == ch]    
    if np.any((strax.endtime(rc)[:-1] - rc['time'][1:]) < 0):
        print(f'Found overlapping records in {ch}') 

Overlapping records can be found in multiple channels:

Found overlapping records in 0
Found overlapping records in 1
Found overlapping records in 2
...

If I change the WFsim config to disable the checks for overlaps in the raw records I can get the records without error messages:

st.set_config(dict(check_raw_record_overlaps=False,
                   fax_file= instructions_file,
                   ))

When running

EventInfo = st.get_df(run_id,'event_info')

I get this error: ValueError: Peaks got inconsistent time ranges of inputs: {'peaklets': (-50000, 4999857499), 'merged_s2s': (0, 4999857499)}

Two different defaults for gain_model_nv (forbidden by strax)

When running

st.register(wfsim.RawRecordsFromMcChain)

strax triggers an error:

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/strax/context.py in register(self, plugin_class)
    280                                    ' one of the defaults.'
    281                                    )
--> 282                             raise ValueError(mes)
    283 
    284                 except strax.InvalidConfiguration:

ValueError: Two plugins have a different default value for the same option.
The option "gain_model_nv" in "muVETOHitlets" takes as a default "('CMT_model', ('to_pe_model_nv', 'ONLINE'))"
while in "RawRecordsFromMcChain" the default value is set to "('to_pe_constant', 0.01)".
Please change one of the defaults.

I open the issue here (WFsim) since I guess it can be fixed by changing this guy:

strax.Option('gain_model_nv', default=('to_pe_constant', 0.01), track=False),

... but experts' advice on whether this is the best solution is welcome. I assume there's no default needed for thsi line, but then one needs to always overwrite this model via context (like @petergaemers fixed here: XENONnT/straxen#446), which needs to be clearly documented.

DPE emission is not applied to S2 maps

Current optical maps use QE values provided by Hamamatsu, which are measured by cathode current and, therefore, include DPE emission. In S1 generation, we normalize it to take this effect into account here :

WFSim/wfsim/core.py

Lines 331 to 332 in fac3598

ly = np.squeeze(s1_light_yield_map(positions),
axis=-1)/(1+config['p_double_pe_emision'])
.

However, for S2s it doesn't seem to be the case, what will result in g2 overestimated by DPE fraction (QE includes DPE and we add it later again). Here is the corresponding part :

WFSim/wfsim/core.py

Lines 542 to 543 in fac3598

sc_gain = np.squeeze(resource.s2_light_yield_map(positions), axis=-1) \
* config['s2_secondary_sc_gain']

Should we simply add the same factor as we used in S1 generation to fix it?

Afterpulses need to be disabled for (NR) simulations from G4

Thanks @petergaemers for debugging! Basically, I produced an instructions file coming from the G4 output of a neutron simulation. In order to not run into problems with chunks and reverse times, entries in a single event are ordered by time where

  • 1st event starts at 1us
  • 2nd event starts at 1s + 1us
  • 3rd event starts at 2s + 1us
  • etc.

The file is located under /dali/lgrandi/ramirezd/test_instructions_for_Peter_0.csv. Running it with

st = straxen.contexts.xenonnt_simulation()
st.set_config(dict(check_raw_record_overlaps=False,
                    fax_file='test_instructions.csv'))

leads to errors related to one chunk endings after the next one has started, or related to the chunk ending after the chunk said it ended.

Things work nicely when running WFsim this way:

st.set_config(dict(check_raw_record_overlaps=False,
                   fax_file='test_instructions.csv',
                   chunk_size=30,
                   fax_config_override=dict(enable_electron_afterpulses=False,
                                           enable_pmt_afterpulses=False),))

but of course we lose the afterpulses (and not sure the chunk size change is not recommended).

Unexpected error when trying to load the config from json profile.

My WFsim version is 0.4.1
I was trying to load the configure needed
config = straxen.get_resource('https://raw.githubusercontent.com/XENONnT/' 'strax_auxiliary_files/master/fax_files/fax_config_nt.json', fmt='json') config.update({'detector':'XENONnT'})
Then it raise the unexpected error, does anyone know what causes the problem and how to solve it?
`---------------------------------------------------------------------------
UnexpectedCharacters Traceback (most recent call last)
/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/commentjson/commentjson.py in loads(text, *args, **kwargs)
179 try:
--> 180 parsed = _remove_trailing_commas(parser.parse(text))
181 final_text = serializer.reconstruct(parsed)

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/lark/lark.py in parse(self, text, start)
310 """
--> 311 return self.parser.parse(text, start=start)
312

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/lark/parser_frontends.py in parse(self, text, start)
88 sps = self.lexer.set_parser_state
---> 89 return self._parse(token_stream, start, *[sps] if sps is not NotImplemented else [])
90

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/lark/parser_frontends.py in _parse(self, input, start, *args)
53 start ,= start
---> 54 return self.parser.parse(input, start, *args)
55

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/lark/parsers/lalr_parser.py in parse(self, *args)
35 def parse(self, *args):
---> 36 return self.parser.parse(*args)
37

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/lark/parsers/lalr_parser.py in parse(self, seq, start, set_state)
83 # Main LALR-parser loop
---> 84 for token in stream:
85 while True:

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/lark/lexer.py in lex(self, stream)
372 try:
--> 373 for x in l.lex(stream, self.root_lexer.newline_types, self.root_lexer.ignore_types):
374 yield x

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/lark/lexer.py in lex(self, stream, newline_types, ignore_types)
173 allowed = {""}
--> 174 raise UnexpectedCharacters(stream, line_ctr.char_pos, line_ctr.line, line_ctr.column, allowed=allowed, state=self.state, token_history=last_token and [last_token])
175

UnexpectedCharacters: No terminal defined for 'I' at line 2060 col 22

"max_intervals": Infinity,
                 ^

Expecting: {'SIGNED_NUMBER', 'FALSE', 'NULL', 'TRUE', 'ESCAPED_STRING', 'LBRACE', 'LSQB'}

Previous tokens: Token(COLON, ':')

During handling of the above exception, another exception occurred:

ValueError Traceback (most recent call last)
/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/commentjson/commentjson.py in load(fp, **kwargs)
214 try:
--> 215 return loads(fp.read(), **kwargs)
216 except Exception as e:

/opt/XENONnT/anaconda/envs/XENONnT_development/lib/python3.8/site-packages/commentjson/commentjson.py in loads(text, *args, **kwargs)
182 except lark.exceptions.UnexpectedCharacters:
--> 183 raise ValueError('Unable to parse text', text)
184

ValueError: ('Unable to parse text', '{\n "anode_field_domination_distance": 0.036,\n "anode_voltage": 4000.0,\n "anode_wire_radius": 0.011749999999999998,\n "channels_bottom": [\n 253,\n 254,\n 255,\n 256,\n 257,\n 258,\n 259,\n 260,\n 261,\n 262,\n 263,\n 264,\n 265,\n 266,\n 267,\n 268,\n 269,\n 270,\n 271,\n 272,\n 273,\n 274,\n 275,\n 276,\n 277,\n 278,\n 279,\n 280,\n 281,\n 282,\n 283,\n 284,\n 285,\n 286,\n 287,\n 288,\n 289,\n 290,\n 291,\n 292,\n 293,\n 294,\n 295,\n 296,\n 297,\n 298,\n 299,\n 300,\n 301,\n 302,\n 303,\n 304,\n 305,\n 306,\n 307,\n 308,\n 309,\n 310,\n 311,\n 312,\n 313,\n 314,\n 315,\n 316,\n 317,\n 318,\n 319,\n 320,\n 321,\n 322,\n 323,\n 324,\n 325,\n 326,\n 327,\n 328,\n 329,\n 330,\n 331,\n 332,\n 333,\n 334,\n 335,\n 336,\n 337,\n 338,\n 339,\n 340,\n 341,\n 342,\n 343,\n 344,\n 345,\n 346,\n 347,\n 348,\n 349,\n 350,\n 351,\n 352,\n 353,\n 354,\n 355,\n 356,\n 357,\n 358,\n 359,\n 360,\n 361,\n 362,\n 363,\n 364,\n 365,\n 366,\n 367,\n 368,\n 369,\n 370,\n 371,\n 372,\n 373,\n 374,\n 375,\n 376,\n 377,\n 378,\n 379,\n 380,\n 381,\n 382,\n 383,\n 384,\n 385,\n 386,\n 387,\n 388,\n 389,\n 390,\n 391,\n 392,\n 393,\n 394,\n 395,\n 396,\n 397,\n 398,\n 399,\n 400,\n 401,\n 402,\n 403,\n 404,\n 405,\n 406,\n 407,\n 408,\n 409,\n 410,\n 411,\n 412,\n 413,\n 414,\n 415,\n 416,\n 417,\n 418,\n 419,\n 420,\n 421,\n 422,\n 423,\n 424,\n 425,\n 426,\n 427,\n 428,\n 429,\n 430,\n 431,\n 432,\n 433,\n 434,\n 435,\n 436,\n 437,\n 438,\n 439,\n 440,\n 441,\n 442,\n 443,\n 444,\n 445,\n 446,\n 447,\n 448,\n 449,\n 450,\n 451,\n 452,\n 453,\n 454,\n 455,\n 456,\n 457,\n 458,\n 459,\n 460,\n 461,\n 462,\n 463,\n 464,\n 465,\n 466,\n 467,\n 468,\n 469,\n 470,\n 471,\n 472,\n 473,\n 474,\n 475,\n 476,\n 477,\n 478,\n 479,\n 480,\n 481,\n 482,\n 483,\n 484,\n 485,\n 486,\n 487,\n 488,\n 489,\n 490,\n 491,\n 492,\n 493\n ],\n "channels_in_detector": {\n "busy_off": [\n 256\n ],\n "busy_on": [\n 255\n ],\n "hev_off": [\n 258\n ],\n "hev_on": [\n 257\n ],\n "muon_veto_trigger": [\n 259\n ],\n "sum_signal": 800,\n "sum_wv": [\n 254\n ],\n "tpc": [\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 11,\n 12,\n 13,\n 14,\n 15,\n 16,\n 17,\n 18,\n 19,\n 20,\n 21,\n 22,\n 23,\n 24,\n 25,\n 26,\n 27,\n 28,\n 29,\n 30,\n 31,\n 32,\n 33,\n 34,\n 35,\n 36,\n 37,\n 38,\n 39,\n 40,\n 41,\n 42,\n 43,\n 44,\n 45,\n 46,\n 47,\n 48,\n 49,\n 50,\n 51,\n 52,\n 53,\n 54,\n 55,\n 56,\n 57,\n 58,\n 59,\n 60,\n 61,\n 62,\n 63,\n 64,\n 65,\n 66,\n 67,\n 68,\n 69,\n 70,\n 71,\n 72,\n 73,\n 74,\n 75,\n 76,\n 77,\n 78,\n 79,\n 80,\n 81,\n 82,\n 83,\n 84,\n 85,\n 86,\n 87,\n 88,\n 89,\n 90,\n 91,\n 92,\n 93,\n 94,\n 95,\n 96,\n 97,\n 98,\n 99,\n 100,\n 101,\n 102,\n 103,\n 104,\n 105,\n 106,\n 107,\n 108,\n 109,\n 110,\n 111,\n 112,\n 113,\n 114,\n 115,\n 116,\n 117,\n 118,\n 119,\n 120,\n 121,\n 122,\n 123,\n 124,\n 125,\n 126,\n 127,\n 128,\n 129,\n 130,\n 131,\n 132,\n 133,\n 134,\n 135,\n 136,\n 137,\n 138,\n 139,\n 140,\n 141,\n 142,\n 143,\n 144,\n 145,\n 146,\n 147,\n 148,\n 149,\n 150,\n 151,\n 152,\n 153,\n 154,\n 155,\n 156,\n 157,\n 158,\n 159,\n 160,\n 161,\n 162,\n 163,\n 164,\n 165,\n 166,\n 167,\n 168,\n 169,\n 170,\n 171,\n 172,\n 173,\n 174,\n 175,\n 176,\n 177,\n 178,\n 179,\n 180,\n 181,\n 182,\n 183,\n 184,\n 185,\n 186,\n 187,\n 188,\n 189,\n 190,\n 191,\n 192,\n 193,\n 194,\n 195,\n 196,\n 197,\n 198,\n 199,\n 200,\n 201,\n 202,\n 203,\n 204,\n 205,\n 206,\n 207,\n 208,\n 209,\n 210,\n 211,\n 212,\n 213,\n 214,\n 215,\n 216,\n 217,\n 218,\n 219,\n 220,\n 221,\n 222,\n 223,\n 224,\n 225,\n 226,\n 227,\n 228,\n 229,\n 230,\n 231,\n 232,\n 233,\n 234,\n 235,\n 236,\n 237,\n 238,\n 239,\n 240,\n 241,\n 242,\n 243,\n 244,\n 245,\n 246,\n 247,\n 248,\n 249,\n 250,\n 251,\n 252,\n 253,\n 254,\n 255,\n 256,\n 257,\n 258,\n 259,\n 260,\n 261,\n 262,\n 263,\n 264,\n 265,\n 266,\n 267,\n 268,\n 269,\n 270,\n 271,\n 272,\n 273,\n 274,\n 275,\n 276,\n 277,\n 278,\n 279,\n 280,\n 281,\n 282,\n 283,\n 284,\n 285,\n 286,\n 287,\n 288,\n 289,\n 290,\n 291,\n 292,\n 293,\n 294,\n 295,\n 296,\n 297,\n 298,\n 299,\n 300,\n 301,\n 302,\n 303,\n 304,\n 305,\n 306,\n 307,\n 308,\n 309,\n 310,\n 311,\n 312,\n 313,\n 314,\n 315,\n 316,\n 317,\n 318,\n 319,\n 320,\n 321,\n 322,\n 323,\n 324,\n 325,\n 326,\n 327,\n 328,\n 329,\n 330,\n 331,\n 332,\n 333,\n 334,\n 335,\n 336,\n 337,\n 338,\n 339,\n 340,\n 341,\n 342,\n 343,\n 344,\n 345,\n 346,\n 347,\n 348,\n 349,\n 350,\n 351,\n 352,\n 353,\n 354,\n 355,\n 356,\n 357,\n 358,\n 359,\n 360,\n 361,\n 362,\n 363,\n 364,\n 365,\n 366,\n 367,\n 368,\n 369,\n 370,\n 371,\n 372,\n 373,\n 374,\n 375,\n 376,\n 377,\n 378,\n 379,\n 380,\n 381,\n 382,\n 383,\n 384,\n 385,\n 386,\n 387,\n 388,\n 389,\n 390,\n 391,\n 392,\n 393,\n 394,\n 395,\n 396,\n 397,\n 398,\n 399,\n 400,\n 401,\n 402,\n 403,\n 404,\n 405,\n 406,\n 407,\n 408,\n 409,\n 410,\n 411,\n 412,\n 413,\n 414,\n 415,\n 416,\n 417,\n 418,\n 419,\n 420,\n 421,\n 422,\n 423,\n 424,\n 425,\n 426,\n 427,\n 428,\n 429,\n 430,\n 431,\n 432,\n 433,\n 434,\n 435,\n 436,\n 437,\n 438,\n 439,\n 440,\n 441,\n 442,\n 443,\n 444,\n 445,\n 446,\n 447,\n 448,\n 449,\n 450,\n 451,\n 452,\n 453,\n 454,\n 455,\n 456,\n 457,\n 458,\n 459,\n 460,\n 461,\n 462,\n 463,\n 464,\n 465,\n 466,\n 467,\n 468,\n 469,\n 470,\n 471,\n 472,\n 473,\n 474,\n 475,\n 476,\n 477,\n 478,\n 479,\n 480,\n 481,\n 482,\n 483,\n 484,\n 485,\n 486,\n 487,\n 488,\n 489,\n 490,\n 491,\n 492,\n 493\n ],\n "veto": [\n 248,\n 249,\n 250,\n 251,\n 252,\n 253\n ]\n },\n "channels_top": [\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 11,\n 12,\n 13,\n 14,\n 15,\n 16,\n 17,\n 18,\n 19,\n 20,\n 21,\n 22,\n 23,\n 24,\n 25,\n 26,\n 27,\n 28,\n 29,\n 30,\n 31,\n 32,\n 33,\n 34,\n 35,\n 36,\n 37,\n 38,\n 39,\n 40,\n 41,\n 42,\n 43,\n 44,\n 45,\n 46,\n 47,\n 48,\n 49,\n 50,\n 51,\n 52,\n 53,\n 54,\n 55,\n 56,\n 57,\n 58,\n 59,\n 60,\n 61,\n 62,\n 63,\n 64,\n 65,\n 66,\n 67,\n 68,\n 69,\n 70,\n 71,\n 72,\n 73,\n 74,\n 75,\n 76,\n 77,\n 78,\n 79,\n 80,\n 81,\n 82,\n 83,\n 84,\n 85,\n 86,\n 87,\n 88,\n 89,\n 90,\n 91,\n 92,\n 93,\n 94,\n 95,\n 96,\n 97,\n 98,\n 99,\n 100,\n 101,\n 102,\n 103,\n 104,\n 105,\n 106,\n 107,\n 108,\n 109,\n 110,\n 111,\n 112,\n 113,\n 114,\n 115,\n 116,\n 117,\n 118,\n 119,\n 120,\n 121,\n 122,\n 123,\n 124,\n 125,\n 126,\n 127,\n 128,\n 129,\n 130,\n 131,\n 132,\n 133,\n 134,\n 135,\n 136,\n 137,\n 138,\n 139,\n 140,\n 141,\n 142,\n 143,\n 144,\n 145,\n 146,\n 147,\n 148,\n 149,\n 150,\n 151,\n 152,\n 153,\n 154,\n 155,\n 156,\n 157,\n 158,\n 159,\n 160,\n 161,\n 162,\n 163,\n 164,\n 165,\n 166,\n 167,\n 168,\n 169,\n 170,\n 171,\n 172,\n 173,\n 174,\n 175,\n 176,\n 177,\n 178,\n 179,\n 180,\n 181,\n 182,\n 183,\n 184,\n 185,\n 186,\n 187,\n 188,\n 189,\n 190,\n 191,\n 192,\n 193,\n 194,\n 195,\n 196,\n 197,\n 198,\n 199,\n 200,\n 201,\n 202,\n 203,\n 204,\n 205,\n 206,\n 207,\n 208,\n 209,\n 210,\n 211,\n 212,\n 213,\n 214,\n 215,\n 216,\n 217,\n 218,\n 219,\n 220,\n 221,\n 222,\n 223,\n 224,\n 225,\n 226,\n 227,\n 228,\n 229,\n 230,\n 231,\n 232,\n 233,\n 234,\n 235,\n 236,\n 237,\n 238,\n 239,\n 240,\n 241,\n 242,\n 243,\n 244,\n 245,\n 246,\n 247,\n 248,\n 249,\n 250,\n 251,\n 252\n ],\n "channels_top_high_energy": [\n 500,\n 501,\n 502,\n 503,\n 504,\n 505,\n 506,\n 507,\n 508,\n 509,\n 510,\n 511,\n 512,\n 513,\n 514,\n 515,\n 516,\n 517,\n 518,\n 519,\n 520,\n 521,\n 522,\n 523,\n 524,\n 525,\n 526,\n 527,\n 528,\n 529,\n 530,\n 531,\n 532,\n 533,\n 534,\n 535,\n 536,\n 537,\n 538,\n 539,\n 540,\n 541,\n 542,\n 543,\n 544,\n 545,\n 546,\n 547,\n 548,\n 549,\n 550,\n 551,\n 552,\n 553,\n 554,\n 555,\n 556,\n 557,\n 558,\n 559,\n 560,\n 561,\n 562,\n 563,\n 564,\n 565,\n 566,\n 567,\n 568,\n 569,\n 570,\n 571,\n 572,\n 573,\n 574,\n 575,\n 576,\n 577,\n 578,\n 579,\n 580,\n 581,\n 582,\n 583,\n 584,\n 585,\n 586,\n 587,\n 588,\n 589,\n 590,\n 591,\n 592,\n 593,\n 594,\n 595,\n 596,\n 597,\n 598,\n 599,\n 600,\n 601,\n 602,\n 603,\n 604,\n 605,\n 606,\n 607,\n 608,\n 609,\n 610,\n 611,\n 612,\n 613,\n 614,\n 615,\n 616,\n 617,\n 618,\n 619,\n 620,\n 621,\n 622,\n 623,\n 624,\n 625,\n 626,\n 627,\n 628,\n 629,\n 630,\n 631,\n 632,\n 633,\n 634,\n 635,\n 636,\n 637,\n 638,\n 639,\n 640,\n 641,\n 642,\n 643,\n 644,\n 645,\n 646,\n 647,\n 648,\n 649,\n 650,\n 651,\n 652,\n 653,\n 654,\n 655,\n 656,\n 657,\n 658,\n 659,\n 660,\n 661,\n 662,\n 663,\n 664,\n 665,\n 666,\n 667,\n 668,\n 669,\n 670,\n 671,\n 672,\n 673,\n 674,\n 675,\n 676,\n 677,\n 678,\n 679,\n 680,\n 681,\n 682,\n 683,\n 684,\n 685,\n 686,\n 687,\n 688,\n 689,\n 690,\n 691,\n 692,\n 693,\n 694,\n 695,\n 696,\n 697,\n 698,\n 699,\n 700,\n 701,\n 702,\n 703,\n 704,\n 705,\n 706,\n 707,\n 708,\n 709,\n 710,\n 711,\n 712,\n 713,\n 714,\n 715,\n 716,\n 717,\n 718,\n 719,\n 720,\n 721,\n 722,\n 723,\n 724,\n 725,\n 726,\n 727,\n 728,\n 729,\n 730,\n 731,\n 732,\n 733,\n 734,\n 735,\n 736,\n 737,\n 738,\n 739,\n 740,\n 741,\n 742,\n 743,\n 744,\n 745,\n 746,\n 747,\n 748,\n 749,\n 750,\n 751,\n 752\n ],\n "diffusion_constant_liquid": 2.935e-08,\n "digitizer_bits": 14,\n "digitizer_reference_baseline": 16000,\n "digitizer_voltage_range": 2.25,\n "drift_field": 82.0,\n "drift_time_gate": 1700.0,\n "drift_velocity_liquid": 0.0001335,\n "electron_extraction_yield": 1,\n "electron_lifetime_liquid": 550000.0,\n "electron_trapping_time": 140.0,\n "elr_gas_gap_length": 0.266,\n "external_amplification": 10,\n "gain_sigmas": [\n 999568.5682,\n 0.0,\n 922435.75872,\n 873204.5660799999,\n 1659308.63891,\n 949916.6459900001,\n 2093318.93056,\n 971466.81123,\n 985542.1550999999,\n 1517456.79792,\n 1006135.6168800001,\n 1304943.3684,\n 0.0,\n 1392094.88163,\n 960624.69358,\n 1074950.91464,\n 1182368.82852,\n 981020.54526,\n 1024069.9487800001,\n 935229.43212,\n 993037.4586,\n 940436.2423800001,\n 1843331.48041,\n 970560.983,\n 1392159.1137299999,\n 977554.29993,\n 0.0,\n 0.0,\n 1015010.1961999999,\n 1010973.0446399999,\n 1632966.73946,\n 936213.8114,\n 1763242.20764,\n 987053.5881899999,\n 0.0,\n 1407135.3785099997,\n 960913.49276,\n 948494.6220399999,\n 1687671.3064400002,\n 1379692.7862,\n 944340.1714500001,\n 1350401.02424,\n 1643720.3078,\n 962523.9131299999,\n 1180344.48304,\n 1066661.62512,\n 943310.0724000001,\n 1509553.91007,\n 982352.12015,\n 1399239.1597600002,\n 1639577.7708400001,\n 0.0,\n 1030856.1826099999,\n 870699.8420999999,\n 1474166.3194100002,\n 804566.3346000001,\n 1922994.93322,\n 1502296.36146,\n 874603.2928399999,\n 950663.5523999999,\n 1193245.5248999998,\n 924137.6559199999,\n 0.0,\n 1590318.55392,\n 1555616.40467,\n 0.0,\n 949641.00669,\n 992357.35852,\n 2081216.59118,\n 1261011.13232,\n 1506099.0755699999,\n 892977.24876,\n 931008.0567000001,\n 0.0,\n 2011108.13387,\n 2024306.34189,\n 1271717.8025,\n 1486395.56956,\n 806254.64192,\n 0.0,\n 1454510.5580199999,\n 1846730.19611,\n 1909214.57892,\n 871343.7840000001,\n 1102426.6388400001,\n 951381.77375,\n 0.0,\n 973835.38112,\n 0.0,\n 1087899.9575,\n 984930.4855499999,\n 0.0,\n 1431505.01704,\n 893207.0848999999,\n 1238525.04293,\n 1784639.87812,\n 1967350.56867,\n 1232714.3700599999,\n 893515.45653,\n 945268.7266199999,\n 950235.3835,\n 1306633.71564,\n 0.0,\n 992821.9328999999,\n 1544332.1257,\n 1672665.9003,\n 1632573.5729599998,\n 925175.46693,\n 2060370.5679,\n 928813.0694400001,\n 1035082.89079,\n 988843.20684,\n 966668.0881299999,\n 1112804.32428,\n 1224921.59772,\n 741214.85222,\n 1608102.2403600002,\n 857262.41964,\n 0.0,\n 969232.9975399999,\n 1028977.1750999999,\n 2058141.57992,\n 968984.87712,\n 952390.5267999999,\n 926414.6257600001,\n 987370.13984,\n 2061468.6899800003,\n 2081297.4226199999,\n 1003617.4974600001,\n 1130978.1181,\n 0.0,\n 1451437.61222,\n 2121835.6665000003,\n 1414730.2812,\n 0.0,\n 0.0,\n 1652786.9073899998,\n 0.0,\n 1987863.67368,\n 0.0,\n 2061354.6234,\n 1360691.52618,\n 885087.24112,\n 1437859.81625,\n 1105572.4002,\n 1344854.86839,\n 1672393.9365,\n 2062684.43552,\n 0.0,\n 981867.67409,\n 0.0,\n 1703060.12194,\n 0.0,\n 1454797.79928,\n 1290445.2038,\n 958940.70944,\n 1452173.87778,\n 987146.54661,\n 1892513.7263999998,\n 1775401.47605,\n 964131.8702400001,\n 1000359.43632,\n 0.0,\n 912781.00368,\n 952943.1911999999,\n 1073350.2648,\n 1023267.5128,\n 0.0,\n 969037.6855799999,\n 1961398.73553,\n 2045677.7408099996,\n 1404589.06016,\n 1680264.58942,\n 962030.82682,\n 913173.4193699999,\n 1808284.65246,\n 1140335.1523799999,\n 1229151.4869199998,\n 0.0,\n 969716.9342500002,\n 2031899.3518200002,\n 2087964.75375,\n 1360287.0180000002,\n 0.0,\n 1011786.47346,\n 1843020.55379,\n 1690160.42991,\n 1715000.0013599999,\n 965049.6031799999,\n 980395.50737,\n 2073778.43764,\n 1133745.57056,\n 1526717.6918000001,\n 1943526.9351899999,\n 1473368.9068600002,\n 966793.0080000001,\n 949186.5678399999,\n 960970.73154,\n 0.0,\n 1429289.7339499998,\n 854765.1496000001,\n 1445752.98648,\n 897287.7795000001,\n 0.0,\n 1592154.68472,\n 816638.20354,\n 0.0,\n 1711892.15172,\n 1001401.64376,\n 853668.8832,\n 1369925.0767,\n 1689269.575,\n 1830876.69442,\n 0.0,\n 0.0,\n 2021811.5650499999,\n 1722900.3191999998,\n 881803.4966,\n 2029318.9571200002,\n 1981688.0969599998,\n 975121.29903,\n 1984164.97813,\n 1419713.06722,\n 1990518.3480000002,\n 1316984.92383,\n 906290.5764199999,\n 1978179.54295,\n 1151652.4065999999,\n 1134114.9721,\n 1923548.9922,\n 976630.60404,\n 1605541.62825,\n 981331.7745299999,\n 1017070.4853599999,\n 0.0,\n 1983538.43518,\n 939577.7654,\n 976041.35265,\n 1931986.37333,\n 0.0,\n 983123.8067200001,\n 1853352.1352000001,\n 1990946.32083,\n 1894769.1424,\n 0.0,\n 1790729.2323000003,\n 1467867.60297,\n 1965522.6807999997,\n 700000.0,\n 700000.0,\n 700000.0,\n 700000.0,\n 700000.0,\n 700000.0,\n 28000.0,\n 35000.0,\n 35000.0,\n 35000.0,\n 35000.0,\n 35000.0\n ],\n "gains": [\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125,\n 2974800.2125\n ],\n "gas_drift_velocity_slope": 5400000000000.0,\n "gate_to_anode_distance": 0.5,\n "gauss_noise_sigmas": null,\n "high_energy_deamplification_factor": 0.05,\n "led_pulse_length": 100.0,\n "liquid_density": 1.872452802978054e+30,\n "lxe_dielectric_constant": 1.874,\n "max_intervals": Infinity,\n "maximum_recombination_time": 50.0,\n "n_channels": 260,\n "noise_file_folder": "/Users/petergaemers/Desktop/python/WFSimDev/real_noise_sample/real_noise_sample/",\n "noise_file_index": "/Users/petergaemers/Desktop/python/WFSimDev/real_noise_sample/real_noise_sample/noise_file_index.txt",\n "nominal_gain": 2000000.0,\n "p_double_pe_emision": 0.15,\n "pe_pulse_ts": [\n -13,\n -12,\n -11,\n -10,\n -9,\n -8,\n -7,\n -6,\n -5,\n -4,\n -3,\n -2,\n -1,\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 11,\n 12,\n 13,\n 14,\n 15,\n 16,\n 17,\n 18,\n 19,\n 20,\n 21,\n 22,\n 23,\n 24,\n 25,\n 26,\n 27,\n 28,\n 29,\n 30,\n 31,\n 32,\n 33,\n 34,\n 35,\n 36,\n 37,\n 38,\n 39,\n 40,\n 41,\n 42,\n 43,\n 44,\n 45,\n 46,\n 47,\n 48,\n 49,\n 50,\n 51,\n 52,\n 53,\n 54,\n 55,\n 56,\n 57,\n 58,\n 59,\n 60,\n 61,\n 62,\n 63,\n 64,\n 65,\n 66,\n 67,\n 68,\n 69,\n 70,\n 71,\n 72,\n 73,\n 74,\n 75,\n 76,\n 77,\n 78,\n 79,\n 80,\n 81,\n 82,\n 83,\n 84,\n 85,\n 86,\n 87,\n 88,\n 89,\n 90,\n 91,\n 92,\n 93,\n 94,\n 95,\n 96,\n 97,\n 98,\n 99,\n 100,\n 101,\n 102,\n 103,\n 104,\n 105,\n 106,\n 107,\n 108,\n 109,\n 110,\n 111,\n 112,\n 113,\n 114,\n 115,\n 116,\n 117,\n 118,\n 119,\n 120,\n 121,\n 122,\n 123,\n 124,\n 125,\n 126,\n 127,\n 128,\n 129,\n 130,\n 131,\n 132,\n 133,\n 134,\n 135,\n 136,\n 137,\n 138,\n 139,\n 140,\n 141,\n 142,\n 143,\n 144,\n 145,\n 146,\n 147,\n 148,\n 149,\n 150,\n 151,\n 152,\n 153,\n 154,\n 155,\n 156,\n 157,\n 158,\n 159,\n 160,\n 161,\n 162,\n 163,\n 164,\n 165,\n 166,\n 167,\n 168,\n 169,\n 170,\n 171,\n 172,\n 173,\n 174,\n 175,\n 176,\n 177,\n 178,\n 179,\n 180,\n 181,\n 182,\n 183,\n 184,\n 185,\n 186,\n 187,\n 188,\n 189,\n 190,\n 191,\n 192,\n 193,\n 194,\n 195\n ],\n "pe_pulse_ys": [\n 5.877972164179458e-09,\n 8.655525785456122e-08,\n 9.494125588317938e-07,\n 7.896805563760717e-06,\n 5.0878565098147255e-05,\n 0.00025904060183682944,\n 0.0010546866894903517,\n 0.0034372690428190844,\n 0.008918175306240714,\n 0.018366585294685045,\n 0.03024293464574896,\n 0.04070285285992151,\n 0.04650274440945783,\n 0.04738821191801888,\n 0.045269280688785586,\n 0.0420583181746971,\n 0.03873509136879648,\n 0.035604682980707264,\n 0.03271708669859928,\n 0.03006262425253816,\n 0.027623450572224897,\n 0.025382178597567896,\n 0.023322755583582648,\n 0.021430427093330644,\n 0.019691635654062734,\n 0.018093923795527204,\n 0.016625844803847056,\n 0.01527688071229399,\n 0.014037366945928706,\n 0.012898423080313378,\n 0.0117226134274469,\n 0.010654620425448081,\n 0.007486532911462879,\n 0.007122986413393814,\n 0.006759439915324416,\n 0.0063958934172549066,\n 0.006032346919185841,\n 0.005668800421116332,\n 0.005305253923046934,\n 0.004954040729682673,\n 0.004615160841022549,\n 0.004498280437047894,\n 0.004381400033073238,\n 0.004264519629098583,\n 0.004147639225123928,\n 0.004030758821149161,\n 0.003913878417174506,\n 0.0037969980131998507,\n 0.0036801176092253066,\n 0.0035661831429826276,\n 0.0034551946144725913,\n 0.0033972329651430124,\n 0.003339271315813323,\n 0.003281309666483744,\n 0.0032233480171541657,\n 0.003165386367824587,\n 0.0031074247184950084,\n 0.0030494630691652075,\n 0.002991501419835629,\n 0.0029345925847569037,\n 0.002878736563928587,\n 0.002841831199613188,\n 0.002804925835297788,\n 0.0027680204709823884,\n 0.0027311151066669887,\n 0.0026942097423514784,\n 0.0026573043780361897,\n 0.002620399013720679,\n 0.002583493649405279,\n 0.0025470331080403733,\n 0.0025110173896258497,\n 0.002483008484319546,\n 0.0024549995790133527,\n 0.0024269906737071595,\n 0.002398981768400855,\n 0.002370972863094662,\n 0.0023429639577884688,\n 0.0023149550524821645,\n 0.0022869461471758602,\n 0.0022592201366423946,\n 0.002231777020881435,\n 0.0022094260110277998,\n 0.0021870750011742757,\n 0.0021647239913207515,\n 0.002142372981467338,\n 0.002120021971613703,\n 0.0020976709617601787,\n 0.0020753199519066546,\n 0.002052968942053241,\n 0.0020307543953674546,\n 0.00200867631184985,\n 0.001989054565354189,\n 0.001969432818858306,\n 0.0019498110723626448,\n 0.0019301893258668727,\n 0.0019105675793713226,\n 0.0018909458328754394,\n 0.0018713240863797783,\n 0.0018517023398840063,\n 0.0018323263223003487,\n 0.0018131960336284728,\n 0.0017984888653722166,\n 0.0017837816971160714,\n 0.0017690745288597041,\n 0.001754367360603559,\n 0.0017396601923473027,\n 0.0017249530240910464,\n 0.0017102458558346792,\n 0.001695538687578423,\n 0.0016813056397601814,\n 0.0016675467123799547,\n 0.0016623219528827716,\n 0.0016570971933854775,\n 0.0016518724338885165,\n 0.0016466476743912226,\n 0.0016414229148939284,\n 0.0016361981553968564,\n 0.0016309733958997843,\n 0.0016257486364023791,\n 0.0016202321178094528,\n 0.00161442384012045,\n 0.0016033638987052918,\n 0.001592303957290245,\n 0.0015812440158751977,\n 0.0015701840744600396,\n 0.0015591241330449924,\n 0.0015480641916298342,\n 0.001537004250214787,\n 0.0015259443087995179,\n 0.0015148109383005546,\n 0.0015036041387176751,\n 0.001491075615624526,\n 0.0014785470925315991,\n 0.001466018569438339,\n 0.001453490046345301,\n 0.001440961523252152,\n 0.0014284330001590028,\n 0.0014159044770659648,\n 0.0014033759539728158,\n 0.0013911025358676267,\n 0.0013790842227502866,\n 0.0013716577994147816,\n 0.0013642313760793877,\n 0.0013568049527439938,\n 0.001349378529408378,\n 0.0013419521060730952,\n 0.0013345256827375902,\n 0.0013270992594020853,\n 0.0013196728360666916,\n 0.0013122629141418373,\n 0.001304869493627745,\n 0.0012977730985050332,\n 0.0012906767033823215,\n 0.001283580308259388,\n 0.0012764839131367872,\n 0.0012693875180140755,\n 0.0012622911228913638,\n 0.001255194727768541,\n 0.0012480983326459403,\n 0.0012409999123474602,\n 0.0012338994668731004,\n 0.0012267625682346867,\n 0.001219625669596495,\n 0.0012124887709579703,\n 0.0012053518723195566,\n 0.0011982149736811428,\n 0.0011910780750428401,\n 0.0011839411764043154,\n 0.0011768042777659017,\n 0.0011693420067777262,\n 0.0011615543634395673,\n 0.0011479100178038103,\n 0.0011342656721679426,\n 0.0011206213265321859,\n 0.00110697698089654,\n 0.0010933326352606722,\n 0.0010796882896250263,\n 0.0010660439439892696,\n 0.0010523995983534019,\n 0.0010394190161775144,\n 0.0010271021974616074,\n 0.0010267331210240156,\n 0.001026364044586091,\n 0.0010259949681484994,\n 0.0010256258917104636,\n 0.001025256815272983,\n 0.0010248877388350584,\n 0.0010245186623973556,\n 0.001024149585959653,\n 0.0010225269485754907,\n 0.0010196507502449798,\n 0.0009942104548798607,\n 0.0009687701595146309,\n 0.0009433298641495118,\n 0.0009178895687842819,\n 0.000892449273419274,\n 0.000867008978054155,\n 0.000841568682688814,\n 0.0008161283873238061,\n 0.0007904692274874684,\n 0.0007645912031799121,\n 0.0007347736183906416,\n 0.0007049560336012601,\n 0.0006751384488119896,\n 0.0006453208640227192,\n 0.0006155032792334486,\n 0.0005856856944440671,\n 0.0005558681096547966,\n 0.0005260505248655261\n ],\n "photoelectric_modifier": 1,\n "photoelectric_p": 0.001,\n "photoelectric_t_center": -800,\n "photoelectric_t_spread": 250,\n "photoionization_modifier": 1,\n "photon_area_distribution": "XENON1T_spe_distributions.csv",\n "pmt_afterpulse_types": {},\n "pmt_ap_modifier": 1,\n "pmt_ap_t_modifier": 270,\n "pmt_circuit_load_resistor": 8.010882825e-09,\n "pmt_fall_time": 10.0,\n "pmt_pulse_time_rounding": 1.0,\n "pmt_rise_time": 3.0,\n "pmt_transit_time_mean": 46.0,\n "pmt_transit_time_spread": 13.6,\n "pressure": 1.210852812592475e+18,\n "quantum_efficiencies": [\n 0.281,\n 0.283,\n 0.284,\n 0.284,\n 0.286,\n 0.287,\n 0.29,\n 0.293,\n 0.293,\n 0.294,\n 0.295,\n 0.296,\n 0.296,\n 0.297,\n 0.329,\n 0.298,\n 0.299,\n 0.301,\n 0.302,\n 0.304,\n 0.305,\n 0.308,\n 0.308,\n 0.308,\n 0.309,\n 0.309,\n 0.31,\n 0.31,\n 0.31,\n 0.311,\n 0.312,\n 0.314,\n 0.33,\n 0.315,\n 0.315,\n 0.315,\n 0.315,\n 0.316,\n 0.316,\n 0.317,\n 0.319,\n 0.327,\n 0.32,\n 0.32,\n 0.321,\n 0.342,\n 0.322,\n 0.322,\n 0.322,\n 0.322,\n 0.322,\n 0.321,\n 0.323,\n 0.323,\n 0.323,\n 0.323,\n 0.324,\n 0.325,\n 0.325,\n 0.325,\n 0.325,\n 0.325,\n 0.325,\n 0.325,\n 0.325,\n 0.326,\n 0.326,\n 0.326,\n 0.326,\n 0.326,\n 0.319,\n 0.327,\n 0.328,\n 0.328,\n 0.328,\n 0.328,\n 0.328,\n 0.297,\n 0.329,\n 0.329,\n 0.329,\n 0.329,\n 0.329,\n 0.329,\n 0.33,\n 0.33,\n 0.331,\n 0.331,\n 0.331,\n 0.332,\n 0.332,\n 0.332,\n 0.332,\n 0.333,\n 0.334,\n 0.334,\n 0.335,\n 0.336,\n 0.336,\n 0.337,\n 0.338,\n 0.339,\n 0.339,\n 0.34,\n 0.34,\n 0.34,\n 0.35,\n 0.341,\n 0.341,\n 0.341,\n 0.341,\n 0.341,\n 0.341,\n 0.341,\n 0.342,\n 0.342,\n 0.342,\n 0.321,\n 0.342,\n 0.342,\n 0.342,\n 0.342,\n 0.343,\n 0.343,\n 0.345,\n 0.345,\n 0.345,\n 0.404,\n 0.405,\n 0.413,\n 0.352,\n 0.35,\n 0.316,\n 0.36,\n 0.346,\n 0.346,\n 0.347,\n 0.347,\n 0.348,\n 0.347,\n 0.329,\n 0.359,\n 0.374,\n 0.36,\n 0.361,\n 0.361,\n 0.361,\n 0.349,\n 0.394,\n 0.347,\n 0.358,\n 0.38,\n 0.385,\n 0.374,\n 0.376,\n 0.376,\n 0.363,\n 0.349,\n 0.389,\n 0.342,\n 0.357,\n 0.372,\n 0.385,\n 0.396,\n 0.386,\n 0.387,\n 0.376,\n 0.363,\n 0.351,\n 0.389,\n 0.359,\n 0.357,\n 0.371,\n 0.385,\n 0.395,\n 0.4,\n 0.397,\n 0.39,\n 0.376,\n 0.363,\n 0.351,\n 0.359,\n 0.356,\n 0.371,\n 0.385,\n 0.393,\n 0.399,\n 0.401,\n 0.397,\n 0.39,\n 0.378,\n 0.363,\n 0.352,\n 0.343,\n 0.356,\n 0.371,\n 0.385,\n 0.393,\n 0.399,\n 0.397,\n 0.391,\n 0.38,\n 0.363,\n 0.353,\n 0.334,\n 0.315,\n 0.336,\n 0.37,\n 0.384,\n 0.393,\n 0.391,\n 0.391,\n 0.373,\n 0.364,\n 0.353,\n 0.4,\n 0.339,\n 0.356,\n 0.369,\n 0.383,\n 0.382,\n 0.381,\n 0.381,\n 0.364,\n 0.353,\n 0.387,\n 0.357,\n 0.356,\n 0.368,\n 0.367,\n 0.367,\n 0.367,\n 0.366,\n 0.354,\n 0.322,\n 0.334,\n 0.356,\n 0.355,\n 0.354,\n 0.354,\n 0.354,\n 0.354,\n 0.324,\n 0.32,\n 0.383,\n 0.374,\n 0.326,\n 0.324,\n 0.35,\n 0.35,\n 0.35,\n 0.35,\n 0.35,\n 0.35,\n 0,\n 0,\n 0,\n 0,\n 0\n ],\n "real_noise_file": "XENON1T_noise_run5037.npz",\n "real_noise_sample_mode": "incoherent",\n "real_noise_sample_size": 480,\n "relative_gain_error": 0.03,\n "relative_qe_error": 0.02,\n "run_number": 0,\n "rz_position_distortion_map": "XENON1T_FDC_SR1_AdCorrTPF.json.gz",\n "s1_ER_alpha_singlet_fraction": 0.7368421052631579,\n "s1_ER_primary_singlet_fraction": 0.1452991452991453,\n "s1_ER_recombination_fraction": 0.9,\n "s1_ER_recombination_time": 4.276062489602044,\n "s1_ER_secondary_singlet_fraction": 0.4444444444444444,\n "s1_NR_singlet_fraction": 0.8863636363636364,\n "s1_decay_time": 44.77,\n "s1_detection_efficiency": 0.12,\n "s1_model_type": "simple",\n "s1_risetime_threshold": 70,\n "s1_width_threshold": 300,\n "s2_fitted_patterns_file": "XENON1T_s2_xy_fitted_patterns_top_v0.3.0.json.gz",\n "s2_mean_area_fraction_top": -1,\n "s2_secondary_sc_gain": 21.3,\n "sample_duration": 10,\n "samples_after_pulse_center": 20,\n "samples_before_pulse_center": 2,\n "samples_to_store_after": 50,\n "samples_to_store_before": 50,\n "shrink_data_threshold": 5000,\n "singlet_fraction_gas": 0.035,\n "singlet_lifetime_gas": 5.88,\n "singlet_lifetime_liquid": 3.1,\n "special_thresholds": {\n "0": 15,\n "1": 16,\n "10": 15,\n "100": 15,\n "101": 15,\n "102": 15,\n "103": 15,\n "104": 15,\n "105": 15,\n "106": 15,\n "107": 24,\n "108": 16,\n "109": 15,\n "11": 28,\n "110": 21,\n "111": 15,\n "112": 15,\n "113": 15,\n "114": 15,\n "115": 15,\n "116": 15,\n "117": 15,\n "118": 15,\n "119": 15,\n "12": 15,\n "120": 15,\n "121": 15,\n "122": 15,\n "123": 15,\n "124": 15,\n "125": 15,\n "126": 15,\n "127": 68,\n "128": 43,\n "129": 15,\n "13": 17,\n "130": 15,\n "131": 18,\n "132": 18,\n "133": 18,\n "134": 92,\n "135": 15,\n "136": 31,\n "137": 15,\n "138": 17,\n "139": 15,\n "14": 44,\n "140": 17,\n "141": 16,\n "142": 15,\n "143": 30,\n "144": 22,\n "145": 19,\n "146": 43,\n "147": 28,\n "148": 51,\n "149": 23,\n "15": 39,\n "150": 15,\n "151": 15,\n "152": 15,\n "153": 15,\n "154": 19,\n "155": 25,\n "156": 38,\n "157": 16,\n "158": 15,\n "159": 42,\n "16": 15,\n "160": 17,\n "161": 15,\n "162": 15,\n "163": 16,\n "164": 27,\n "165": 20,\n "166": 15,\n "167": 15,\n "168": 15,\n "169": 15,\n "17": 32,\n "170": 32,\n "171": 34,\n "172": 18,\n "173": 15,\n "174": 30,\n "175": 20,\n "176": 30,\n "177": 15,\n "178": 15,\n "179": 23,\n "18": 26,\n "180": 56,\n "181": 16,\n "182": 21,\n "183": 15,\n "184": 21,\n "185": 54,\n "186": 29,\n "187": 48,\n "188": 15,\n "189": 15,\n "19": 15,\n "190": 15,\n "191": 15,\n "192": 35,\n "193": 25,\n "194": 21,\n "195": 26,\n "196": 34,\n "197": 15,\n "198": 17,\n "199": 17,\n "2": 25,\n "20": 30,\n "200": 19,\n "201": 29,\n "202": 16,\n "203": 15,\n "204": 34,\n "205": 27,\n "206": 15,\n "207": 26,\n "208": 15,\n "209": 21,\n "21": 17,\n "210": 22,\n "211": 31,\n "212": 30,\n "213": 15,\n "214": 15,\n "215": 22,\n "216": 65,\n "217": 19,\n "218": 21,\n "219": 33,\n "22": 15,\n "220": 28,\n "221": 30,\n "222": 43,\n "223": 70,\n "224": 19,\n "225": 18,\n "226": 18,\n "227": 15,\n "228": 15,\n "229": 15,\n "23": 15,\n "230": 15,\n "231": 37,\n "232": 15,\n "233": 16,\n "234": 15,\n "235": 59,\n "236": 18,\n "237": 17,\n "238": 54,\n "239": 65,\n "24": 15,\n "240": 20,\n "241": 35,\n "242": 23,\n "243": 22,\n "244": 17,\n "245": 28,\n "246": 42,\n "247": 47,\n "248": 15,\n "249": 15,\n "25": 15,\n "250": 15,\n "251": 15,\n "252": 15,\n "253": 17,\n "254": 100,\n "255": 100,\n "256": 15,\n "257": 15,\n "258": 15,\n "259": 15,\n "26": 15,\n "27": 15,\n "28": 28,\n "29": 15,\n "3": 15,\n "30": 30,\n "31": 15,\n "32": 15,\n "33": 47,\n "34": 15,\n "35": 15,\n "36": 15,\n "37": 15,\n "38": 15,\n "39": 18,\n "4": 15,\n "40": 15,\n "41": 15,\n "42": 15,\n "43": 15,\n "44": 15,\n "45": 15,\n "46": 15,\n "47": 27,\n "48": 55,\n "49": 65,\n "5": 19,\n "50": 76,\n "51": 103,\n "52": 15,\n "53": 15,\n "54": 15,\n "55": 15,\n "56": 15,\n "57": 16,\n "58": 37,\n "59": 15,\n "6": 16,\n "60": 15,\n "61": 33,\n "62": 15,\n "63": 15,\n "64": 19,\n "65": 15,\n "66": 29,\n "67": 15,\n "68": 17,\n "69": 19,\n "7": 15,\n "70": 15,\n "71": 15,\n "72": 15,\n "73": 15,\n "74": 15,\n "75": 27,\n "76": 46,\n "77": 65,\n "78": 39,\n "79": 25,\n "8": 15,\n "80": 15,\n "81": 15,\n "82": 15,\n "83": 15,\n "84": 15,\n "85": 15,\n "86": 15,\n "87": 15,\n "88": 15,\n "89": 17,\n "9": 15,\n "90": 35,\n "91": 15,\n "92": 18,\n "93": 15,\n "94": 16,\n "95": 15,\n "96": 108,\n "97": 19,\n "98": 16,\n "99": 15\n },\n "temperature": 177.45,\n "tight_coincidence_threshold": 2,\n "tight_coincidence_window_left": 50.0,\n "tight_coincidence_window_right": 50.0,\n "tpc_length": 148.1,\n "tpc_name": "XENON1T",\n "tpc_radius": 66.4,\n "trigger_window": 50,\n "triplet_lifetime_gas": 119.5,\n "triplet_lifetime_liquid": 24.0,\n "xy_posrec_preference": [\n "PosRecTopPatternFit",\n "PosRecNeuralNet",\n "PosRecWeightedSum"\n ],\n "zle_threshold": 15\n}')`

New runID argument to communicate with the CMT

Ideally, the user would provide a DAQ run ID and we'd query the corrections at that stage, updating the alerady existing CMT interface in WFsim. For the CMT/straxen experts: which complications do you foresee here?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.