Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added the option to return the full waveform #34

Open
wants to merge 59 commits into
base: caribou
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
bff6dd2
Fix Timepix3 compilation
simonspa Feb 4, 2022
b2e1be5
adding the AD9249 Converter
lhuth Apr 12, 2022
1f4cb7a
firs converter version
lhuth Apr 13, 2022
606927c
Merge branch 'master' of github.com:eudaq/eudaq into caribou
simonspa Apr 13, 2022
8c65e9a
Caribou: allow for "Secondary device" which is only powered and confi…
simonspa Apr 13, 2022
75a6f9a
Caribou/AD9249: rework decoder, add timestamp decoding
lhuth Apr 13, 2022
60e995b
fixing peak det by Spannagel and Buschmann
lhuth Apr 14, 2022
9d8294a
Merge remote-tracking branch 'telepix02/read_ADC' into caribou
simonspa Apr 14, 2022
6b6cab5
ADDecover: add include
simonspa Apr 14, 2022
86087f1
ADDec: change hit detection
simonspa Apr 14, 2022
2ba8be6
AD: add printout for short evt
simonspa Apr 14, 2022
3cfeb77
AD: corrected mapping
simonspa Apr 14, 2022
240097c
AD remove TS for now to match triggers
simonspa Apr 14, 2022
19be585
AD: do not create bogus pixel 0,0
simonspa Apr 14, 2022
20126c0
AD: use difference as charge value, not max
simonspa Apr 14, 2022
7b16ab7
AD: count our own triggers sicne the datacollector re-assigns event n…
simonspa Apr 14, 2022
3646a9f
AD: comment out writing of raw data
simonspa Apr 14, 2022
e0dd80a
AD: fix channel mapping
simonspa Apr 14, 2022
4a341d2
AD: Using two thresholds. One to find seed pixels. And a second one, …
lhuth Apr 25, 2022
b1abb2b
AD: Reduce couts.
lhuth Apr 25, 2022
5a6fb8b
AD: Fix formating.
lhuth Apr 25, 2022
dfe22b6
AD: cout -> EUDAQ_DEBUG
lhuth Apr 25, 2022
f5b1df2
AD: Fix misstakes in EUDAQ_DEBUG statements
lhuth Apr 25, 2022
34cc179
Merge pull request #30 from ffeindt/caribou_apts
simonspa Apr 25, 2022
cab5d4a
AD: Fixed ts_i reset condition.
ffeindt May 2, 2022
51c8cc0
Merge pull request #31 from ffeindt/caribou_apts
simonspa May 2, 2022
1f9bdfc
Make euCliReader accept config files.
ffeindt May 2, 2022
da50daa
ALPIDERawEvent converter can now be configured to make use of timesta…
ffeindt May 2, 2022
8145eec
Also AD9249 converter can now be configured to use time stamps instea…
ffeindt May 2, 2022
4f215b6
AD fixed type overflow in timestamp calculation.
ffeindt May 3, 2022
efe2d56
Adjusting converter configuration.
ffeindt May 4, 2022
51c5a37
Implemented caribou converter for dSiPM device.
ffeindt May 5, 2022
cea72fb
dSiPM: Reworked timestamp calculation.
ffeindt May 5, 2022
3e55048
Fix debug statement and adapt.
ffeindt May 12, 2022
46683c1
Adapted to fix of type issues in peary dSiPM::decodeFrame.
ffeindt May 12, 2022
4874d4a
Caribou: document and improve adc_signal feature
simonspa May 17, 2022
49682d5
Merge pull request #1 from simonspa/caribou_dsipm
ffeindt May 17, 2022
bdf1568
dSiPM: Added trigger counter
ffeindt May 18, 2022
ad252c7
dSiPM: Adapt print statements and moved to event building by trigger id.
ffeindt May 18, 2022
644c78f
dSiPM: Added time stamp printouts to TLU converter for sync checks.
ffeindt May 18, 2022
ead0273
dSiPM: Now deriving frame counter from fpga_trigger id.
ffeindt May 18, 2022
cfe0bde
dSiPM; copy tags from original event
simonspa May 18, 2022
28f6354
Also add offset correction for TLU timestamps.
ffeindt May 21, 2022
5a19293
Correcting also the TLU timestamp.
ffeindt May 24, 2022
721d659
APTS: Correcting rounding misstake in timestamp
ffeindt Jun 1, 2022
a473b88
Caribou: Document secondary_device
simonspa Jun 13, 2022
79e446a
Merge pull request #32 from ffeindt/caribou_apts
simonspa Jun 13, 2022
77af183
Merge pull request #33 from simonspa/caribou_dsipm
simonspa Jun 13, 2022
db57fb7
added the option to return the full waveform
lhuth Jun 27, 2022
461f3c5
writing waveforms to file if filename provided
Jul 28, 2022
f58b120
Run start time taken from event 1 not 0 for ALPIDE and AD9249 convert…
ffeindt Jul 28, 2022
ab1526e
Merge pull request #35 from ffeindt/caribou_lab
simonspa Aug 8, 2022
a5c26ac
merging caribou updates
lhuth Aug 8, 2022
d4c371e
update from eudaq master
lhuth Aug 8, 2022
5b9a5d7
using waveform
lhuth Aug 9, 2022
ee0441f
Merge branch 'master' into caribou
simonspa Aug 10, 2022
a414b36
Merge remote-tracking branch 'spanns/caribou' into waveforms
lhuth Aug 10, 2022
0399e14
Caribou: adding readme for AD9249 converter
lhuth Aug 10, 2022
1bf29c7
style changes
lhuth Aug 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions main/exe/src/euCliReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
int main(int /*argc*/, const char **argv) {
eudaq::OptionParser op("EUDAQ Command Line FileReader modified for TLU", "2.1", "EUDAQ FileReader (TLU)");
eudaq::Option<std::string> file_input(op, "i", "input", "", "string", "input file");
eudaq::Option<std::string> file_conf(op, "c", "config", "", "string", "configuration file");
eudaq::Option<uint32_t> eventl(op, "e", "event", 0, "uint32_t", "event number low");
eudaq::Option<uint32_t> eventh(op, "E", "eventhigh", 0, "uint32_t", "event number high");
eudaq::Option<uint32_t> triggerl(op, "tg", "trigger", 0, "uint32_t", "trigger number low");
Expand All @@ -17,7 +18,6 @@ int main(int /*argc*/, const char **argv) {
eudaq::OptionFlag stdev(op, "std", "stdevent", "enable converter of StdEvent");

op.Parse(argv);

std::string infile_path = file_input.Value();
std::string type_in = infile_path.substr(infile_path.find_last_of(".")+1);
if(type_in=="raw")
Expand All @@ -34,6 +34,25 @@ int main(int /*argc*/, const char **argv) {
uint32_t timestamph_v = timestamph.Value();
bool not_all_zero = eventl_v||eventh_v||triggerl_v||triggerh_v||timestampl_v||timestamph_v;


// load configuration
// empty configuration object, prevents crash if no config file given
eudaq::Configuration eu_cfg( "", "" );
std::ifstream conffile( file_conf.Value() );
if( conffile ){
eu_cfg.Load( conffile, std::string("euCliReader") );
}
// prevent warning if no config file name given
else if ( file_conf.Value().empty() ){}
// but warn if attempt failed
else{
std::cout << "WARNING, config file '" << file_conf.Value() << "' not found!" << std::endl;
}
// build shared pointer
const eudaq::Configuration const_eu_cfg = eu_cfg;
eudaq::ConfigurationSPC config_spc = std::make_shared<const eudaq::Configuration>(const_eu_cfg);


eudaq::FileReaderUP reader;
reader = eudaq::Factory<eudaq::FileReader>::MakeUnique(eudaq::str2hash(type_in), infile_path);
uint32_t event_count = 0;
Expand Down Expand Up @@ -78,11 +97,11 @@ int main(int /*argc*/, const char **argv) {
ev->Print(std::cout);
if(stdev_v){
auto evstd = eudaq::StandardEvent::MakeShared();
eudaq::StdEventConverter::Convert(ev, evstd, nullptr);
eudaq::StdEventConverter::Convert(ev, evstd, config_spc);
std::cout<< ">>>>>"<< evstd->NumPlanes() <<"<<<<"<<std::endl;
}
}

event_count ++;
}
std::cout<< "There are "<< event_count << "Events"<<std::endl;
Expand Down
47 changes: 40 additions & 7 deletions user/ITS3/module/src/ALPIDERawEvent2StdEventConverter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
#include "eudaq/RawEvent.hh"
#include <iostream>


class ALPIDERawEvent2StdEventConverter:public eudaq::StdEventConverter{
public:
bool Converting(eudaq::EventSPC rawev,eudaq::StdEventSP stdev,eudaq::ConfigSPC conf) const override;
private:
void Dump(const std::vector<uint8_t> &data,size_t i) const;
static bool m_configured;
static bool m_useTime;
static std::map<uint32_t,int64_t> m_runStartTimes;
};

bool ALPIDERawEvent2StdEventConverter::m_configured(0);
bool ALPIDERawEvent2StdEventConverter::m_useTime(0);
std::map<uint32_t,int64_t> ALPIDERawEvent2StdEventConverter::m_runStartTimes;

#define REGISTER_CONVERTER(name) namespace{auto dummy##name=eudaq::Factory<eudaq::StdEventConverter>::Register<ALPIDERawEvent2StdEventConverter>(eudaq::cstr2hash(#name));}
REGISTER_CONVERTER(ALPIDE_plane_0)
REGISTER_CONVERTER(ALPIDE_plane_1)
Expand All @@ -32,6 +40,18 @@ REGISTER_CONVERTER(ALPIDE_plane_18)
REGISTER_CONVERTER(ALPIDE_plane_19)

bool ALPIDERawEvent2StdEventConverter::Converting(eudaq::EventSPC in,eudaq::StdEventSP out,eudaq::ConfigSPC conf) const{

// load configuration from config file
if( !m_configured ){
// read from config file
m_useTime = conf->Get("use_time_stamp", false );

EUDAQ_DEBUG( "Using configuration:" );
EUDAQ_DEBUG( " use_time_stamp = " + m_useTime ? "true" : "false");

m_configured = true;
}

auto rawev=std::dynamic_pointer_cast<const eudaq::RawEvent>(in);
std::vector<uint8_t> data=rawev->GetBlock(0); // FIXME: copy?
eudaq::StandardPlane plane(rawev->GetDeviceN(),"ITS3DAQ","ALPIDE");
Expand All @@ -47,12 +67,25 @@ bool ALPIDERawEvent2StdEventConverter::Converting(eudaq::EventSPC in,eudaq::StdE
for (int j=0;j<4;++j) iev|=((uint32_t)data[i+4+j])<<(j*8);
for (int j=0;j<8;++j) tev|=((uint64_t)data[i+8+j])<<(j*8);
tev*=12500; // 80Mhz clks to 1ps


// store time of the run start for each plane
if(iev == 1){
m_runStartTimes.emplace(std::make_pair(rawev->GetDeviceN(), tev));
}

// use timestamps
auto planeStart = m_runStartTimes.find(rawev->GetDeviceN());
if( m_useTime && planeStart != m_runStartTimes.end()){
out->SetTimeBegin(tev - planeStart->second);
out->SetTimeEnd(tev - planeStart->second);
}
// forcing corry to fall back on trigger IDs
out->SetTimeBegin(0);
out->SetTimeEnd(0);
else{
out->SetTimeBegin(0);
out->SetTimeEnd(0);
}
out->SetTriggerN(iev);

i+=16;
uint8_t reg;
if((data[i]&0xF0)==0xE0) {// chip empty frame
Expand Down Expand Up @@ -102,7 +135,7 @@ bool ALPIDERawEvent2StdEventConverter::Converting(eudaq::EventSPC in,eudaq::StdE
Dump(data,i);
return false;
}
}
}
}
else {
EUDAQ_WARN("BAD WORD. No event start? Skipping raw event.");
Expand All @@ -113,7 +146,7 @@ bool ALPIDERawEvent2StdEventConverter::Converting(eudaq::EventSPC in,eudaq::StdE
EUDAQ_WARN("BAD WORD. Bad/no event trailer? Skipping raw event.");
Dump(data,i);
return false;
}
}
out->AddPlane(plane);
return true;
}
Expand All @@ -124,7 +157,7 @@ void ALPIDERawEvent2StdEventConverter::Dump(const std::vector<uint8_t> &data,siz
for (size_t j=0;j<data.size();++j) {
if (i==j)
sprintf(buf,"%06zX: %02X <-- problem around here?",j,data[j]);
else
else
sprintf(buf,"%06zX: %02X",j,data[j]);
EUDAQ_WARN(buf);
}
Expand Down
22 changes: 22 additions & 0 deletions user/caribou/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,19 @@ The producer interfaces the Peary device manager to add devices and to control t

Both keys need to be set, of one or the other is missing, no change of configuration is attempted.

The key `adc_signal` and `adc_frequency` can be used to sample the slow ADC on the Carboard in regular intervals. Here, `adc_signal` is the name of the ADC input channel as assigned via the Peary periphery for the given device, and `adc_frequency` is the number of events after which a new reading is attempted, the default is 1000. If no `adc_signal` is set, no ADC reading is attempted.

The producer itself reads the value `number_of_subevents` which allows buffering. If set to a value larger than zero, events are first buffered and upon reaching the desired buffer depth, they are collectively sent as sub-events of a Caribou event of the same type.
A value of, for example, `number_of_subevents = 100` would therefore result in one event being sent to the DataCollector every 100 events read from the device. This event would contain 100 sub-events with the individual data blocks. This is completely transparent to data analysis performed in Corryvreckan using the EventLoaderEUDAQ2 and can be used to reduce the number of packets sent via the network.

* **Secondary Device**: Sometimes it is necessary to run two devices through Caribou, one of which only requires power and configuration, while the readout happens over the other. For this purpose, the parameter

```toml
secondary_device = "deviceName"
```

can be set. This device will only be powered (via `powerOn()`) and configured (via `configure()`) but no data will be attempted to retrieve. Readout is only performed for the primary device.

* **DAQ Start / Stop**: During DAQ start and stop, the corresponding Peary device functions `daqStart()` and `daqStop()` are called.

Since the Peary device libraries are not thread-safe, all access to Peary libraries is guarded using C++11 `std::lock_guard` with a central class-member mutex to avoid concurrent device access. The Peary device manager itself ensures that no two instances are executed on the same hardware. This means, only one EUDAQ2 producer can be run on each Caribou board.
Expand Down Expand Up @@ -65,3 +75,15 @@ The following parameters can be passed in the configuration in order to influenc

* `clkdivend2`: Value of clkdivend2 register in ATLASPix specifying the speed of TS2 counter. Default is `7`.
* `clock_cycle`: Clock period of the hit timestamps, defaults to `8` (ns). The value needs to be provided in `ns`.


### AD9249Event2StdEventConverter

The following parameters can be passed in the configuration in order to influence the decoding behavior of this module:


* `threshold_trig`:Threshold in ADC counts to accept waveform as "hit". Defaults to 1000
* `threshold_low`: Threshold in ADC counts to add to a cluster with a seed hit with a charge above `threshold_trig`. Defaults to 101
* `use_time_stamp`: Defines if a time stamp is added to the event. Defaults to `false`
* "use_waveform": Copy the full waveform with a pixel hit. If set, `threshold_trig` and `threshold_low` are ignored. Defaults to `false`
* `wavefrom_filename`: Name of a potential file to txt dump the waveforms. Defaultts to "".
Copy link
Owner

Choose a reason for hiding this comment

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

wavefrom_filename -> waveform_filename
Defaultts -> Defaultts

Add that waveform files are only written if filename is not empty.

Copy link
Owner

Choose a reason for hiding this comment

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

and single backticks around use_waveform

28 changes: 28 additions & 0 deletions user/caribou/module/include/CaribouEvent2StdEventConverter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ namespace eudaq {
}
return stream.str();
}
class AD9249Event2StdEventConverter: public eudaq::StdEventConverter{
public:
bool Converting(eudaq::EventSPC d1, eudaq::StandardEventSP d2, eudaq::ConfigurationSPC conf) const override;
static const uint32_t m_id_factory = eudaq::cstr2hash("CaribouAD9249Event");
private:
void decodeChannel(const size_t adc, const std::vector<uint8_t>& data, size_t size, size_t offset, std::vector<std::vector<uint16_t>>& waveforms, uint64_t& timestamp) const;
static size_t trig_;
static bool m_configured;
static bool m_useWaveform;
static bool m_useTime;
static int64_t m_runStartTime;
static int threshold_trig;
static int threshold_low;
static std::string m_waveform_filename;
static std::ofstream m_outfile_waveforms;
};


class CLICTDEvent2StdEventConverter: public eudaq::StdEventConverter{
public:
Expand All @@ -39,6 +56,17 @@ namespace eudaq {
static uint64_t last_shutter_open_;
};

class dSiPMEvent2StdEventConverter: public eudaq::StdEventConverter{
public:
bool Converting(eudaq::EventSPC d1, eudaq::StandardEventSP d2, eudaq::ConfigurationSPC conf) const override;
static const uint32_t m_id_factory = eudaq::cstr2hash("CariboudSiPMEvent");
private:
static bool m_configured;
static bool m_zeroSupp;
static uint64_t m_trigger;
static uint64_t m_frame;
};

class CLICpix2Event2StdEventConverter: public eudaq::StdEventConverter{
public:
bool Converting(eudaq::EventSPC d1, eudaq::StandardEventSP d2, eudaq::ConfigurationSPC conf) const override;
Expand Down
Loading