Commit 97002fd6 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'mupix' into 'master'

Implemented an eventloader for Mupix telescope data and some minor changes listed below

See merge request !102
parents 085f090d 4a758a5a
Pipeline #836102 failed with stages
in 2 minutes and 18 seconds
# - Try to find the MuPix telescope DAQ
# Once done this will define
# MUPIX8DAQ_FOUND - System has MuPixDAQ
# MUPIX8DAQ_INCLUDE_DIR - The MuPixDAQ main include directories
# MUPIX8DAQ_LIBRARY - The libraries needed to use MuPixDAQ
MESSAGE(STATUS "Looking for MuPix Telescope Readout...")
FIND_PATH(MUPIX8DAQ_INCLUDE_DIR NAMES "telescope_frame.hpp" "*.hpp" "*.h" PATHS "$ENV{MUPIX8DAQ}/library")
MESSAGE(STATUS "telescope_frame.hpp => ${MUPIX8DAQ_INCLUDE_DIR}")
IF(MUPIX8DAQ_INCLUDE_DIR)
SET(MUPIX8DAQ_INC_FOUND TRUE)
MESSAGE(STATUS "Found MUPIX8DAQ headers: ${MUPIX8DAQ_INCLUDE_DIR}")
ENDIF()
FIND_LIBRARY(MUPIX8DAQ_LIBRARY NAMES "libtelescope" HINTS "$ENV{MUPIX8DAQ}/build/library")
MESSAGE(STATUS "libMuPix8 => ${MUPIX8DAQ_LIBRARY}")
IF(MUPIX8DAQ_LIBRARY)
SET(MUPIX8DAQ_LIB_FOUND TRUE)
MESSAGE(STATUS "Found MuPix8DAQ library: ${MUPIX8DAQ_LIBRARY}")
ENDIF()
IF(MUPIX8DAQ_LIB_FOUND AND MUPIX8DAQ_INC_FOUND)
SET(MUPIX8DAQ_FOUND TRUE)
MESSAGE(STATUS "MUPIX8DAQ Found true")
ENDIF()
mark_as_advanced(MUPIX8DAQ_LIBRARY MUPIX8DAQ_INCLUDE_DIR)
......@@ -15,6 +15,7 @@ using namespace std;
AlignmentMillepede::AlignmentMillepede(Configuration config, std::vector<std::shared_ptr<Detector>> detectors)
: Module(std::move(config), std::move(detectors)) {
m_excludeDUT = m_config.get<bool>("exclude_dut", false);
m_numberOfTracksForAlignment = m_config.get<size_t>("number_of_tracks", 20000);
m_dofs = m_config.getArray<bool>("dofs", {});
m_nIterations = m_config.get<size_t>("iterations", 5);
......@@ -99,11 +100,11 @@ void AlignmentMillepede::finalise() {
size_t nPlanes = num_detectors();
for(const auto& det : get_detectors()) {
if(det->isDUT()) {
if(det->isDUT() && m_excludeDUT) {
nPlanes--;
}
}
LOG(INFO) << "Aligning " << nPlanes << "planes";
const size_t nParameters = 6 * nPlanes;
for(unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
// Define the constraint equations.
......
......@@ -153,6 +153,8 @@ namespace corryvreckan {
std::vector<unsigned int> m_fixedPlanes;
/// Flag to fix all degrees of freedom or only the translations.
bool m_fix_all;
/// It can be also reasonable to include the DUT in the alignemnt
bool m_excludeDUT;
};
} // namespace corryvreckan
......
......@@ -11,6 +11,8 @@ The Millepede algorthm allows a simultaneous fit of both the tracks and the alig
The modules stops if the convergence, i.e. the absolute sum of all corrections over the total number of parameters, is smaller than the configured value.
### Parameters
* `exclude_dut` : Exclude the DUT from the alignment procedure. Default value
is `false`.
* `number_of_tracks`: Number of tracks used in the alignment method chosen. Default value is `20000`.
* `iterations`: Number of times the chosen alignment method is to be iterated. Default value is `3`.
* `dofs`: Degrees of freedom to be aligned. This parameter should be given as vector of six boolean values for the parameters "Translation X", "Translation Y", "Translation Z", "Rotation X", "Rotation Y" and "Rotation Z". The default setting is an alignment of all parameters except for "Translation Z", i.e. `dofs = true, true, false, true, true, true`.
......@@ -25,4 +27,5 @@ The modules stops if the convergence, i.e. the absolute sum of all corrections o
[Millepede]
iterations = 10
dofs = true, true, false, true, true, true
exclude_dut = false
```
......@@ -189,6 +189,14 @@ void AnalysisDUT::initialise() {
m_detector->nPixels().Y(),
0,
m_detector->nPixels().Y());
hUnassociatedTracksGlobalPosition = new TH2F("hUnassociatedTracksGlobalPosition",
"hUnassociatedTracksGlobalPosition; x / mm; y / mm",
200,
-10,
10,
200,
-10,
10);
}
StatusCode AnalysisDUT::run(std::shared_ptr<Clipboard> clipboard) {
......@@ -278,6 +286,7 @@ StatusCode AnalysisDUT::run(std::shared_ptr<Clipboard> clipboard) {
auto associated_clusters = track->associatedClusters();
if(std::find(associated_clusters.begin(), associated_clusters.end(), cluster) == associated_clusters.end()) {
LOG(DEBUG) << "No associated cluster found";
hUnassociatedTracksGlobalPosition->Fill(globalIntercept.X(), globalIntercept.Y());
continue;
}
......
......@@ -61,7 +61,7 @@ namespace corryvreckan {
TH2F* hAssociatedTracksGlobalPosition;
TH2F* hAssociatedTracksLocalPosition;
TH2F* hUnassociatedTracksGlobalPosition;
// Member variables
double spatialCut, m_timeCutFrameEdge;
double chi2ndofCut;
......
......@@ -17,6 +17,7 @@ Analysis module for CLICpix2 prototypes. This module is still work in progress,
* 2D Map of cluster sizes for associated clusters
* 2D Map of cluster ToT values from associated clusters
* 2D Map of associated hits
* 2D Map of tracks not associated to a cluster
* 2D Map of associated hits within the defined region-of-interest
* Distribution of pixel ToT values from associated clusters
* 2D Map of pixel ToT values from associated clusters
......
......@@ -20,6 +20,7 @@ AnalysisEfficiency::AnalysisEfficiency(Configuration config, std::shared_ptr<Det
m_detector = detector;
m_timeCutFrameEdge = m_config.get<double>("time_cut_frameedge", Units::get<double>(20, "ns"));
m_pixelTolerance = m_config.get<double>("pixel_toleracnce", 1.);
m_chi2ndofCut = m_config.get<double>("chi2ndof_cut", 3.);
}
......@@ -111,8 +112,8 @@ StatusCode AnalysisEfficiency::run(std::shared_ptr<Clipboard> clipboard) {
auto globalIntercept = m_detector->getIntercept(track);
auto localIntercept = m_detector->globalToLocal(globalIntercept);
if(!m_detector->hasIntercept(track, 0.5)) {
LOG(DEBUG) << " - track outside DUT area";
if(!m_detector->hasIntercept(track, m_pixelTolerance)) {
LOG(DEBUG) << " - track outside DUT area: " << localIntercept;
continue;
}
......
......@@ -45,7 +45,7 @@ namespace corryvreckan {
TProfile2D* hChipEfficiencyMap_clustPos;
TProfile2D* hGlobalEfficiencyMap_clustPos;
double m_chi2ndofCut, m_timeCutFrameEdge;
double m_chi2ndofCut, m_timeCutFrameEdge, m_pixelTolerance;
int total_tracks, matched_tracks;
};
......
......@@ -8,6 +8,8 @@
This module measures the efficiency of the device under test by comparing its cluster positions with the interpolated track position at the DUT.
### Parameters
* `pixel_tolerance`: Parameter to discard tracks, which are extrapolated to
the edge of the DUT. Defaults to `1.`, which excludes column/row zero and max.
* `time_cut_frameedge`: Parameter to discard telescope tracks at the frame edges (start and end of the current event window). Defaults to `20ns`.
* `chi2ndof_cut`: Acceptance criterion for telescope tracks, defaults to a value of `3`.
......
......@@ -37,6 +37,16 @@ void ClusteringSpatial::initialise() {
400,
-m_detector->size().Y() / 1.5,
m_detector->size().Y() / 1.5);
title = m_detector->name() + " Cluster Position (Local);x [px];y [px];events";
clusterPositionLocal = new TH2F("clusterPositionLocal",
title.c_str(),
m_detector->nPixels().X(),
-m_detector->nPixels().X() / 2.,
m_detector->nPixels().X() / 2.,
m_detector->nPixels().Y(),
-m_detector->nPixels().Y() / 2.,
m_detector->nPixels().Y() / 2.);
}
StatusCode ClusteringSpatial::run(std::shared_ptr<Clipboard> clipboard) {
......@@ -127,7 +137,8 @@ StatusCode ClusteringSpatial::run(std::shared_ptr<Clipboard> clipboard) {
clusterWidthColumn->Fill(cluster->columnWidth());
clusterTot->Fill(cluster->tot() * 1e-3);
clusterPositionGlobal->Fill(cluster->global().x(), cluster->global().y());
clusterPositionLocal->Fill(cluster->local().x(), cluster->local().y());
LOG(DEBUG) << "cluster local: " << cluster->local();
deviceClusters->push_back(cluster);
}
......
......@@ -33,6 +33,7 @@ namespace corryvreckan {
TH1F* clusterWidthColumn;
TH1F* clusterTot;
TH2F* clusterPositionGlobal;
TH2F* clusterPositionLocal;
};
} // namespace corryvreckan
#endif // ClusteringSpatial_H
......@@ -18,6 +18,7 @@ For each detector the following plots are produced:
* Cluster width (columns, in Y) histogram
* Cluster ToT histogram
* 2D cluster positions in global coordinates
* 2D cluster positions in local coordinates
### Usage
```toml
......
/**
* @file
* @brief Implementation of [Dummy] module
* @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
* Copyright (c) 2019 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
......
/**
* @file
* @brief Definition of [Dummy] module
* @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
* Copyright (c) 2019 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
......
CORRYVRECKAN_ENABLE_DEFAULT(OFF)
# Define module and return the generated name as MODULE_NAME
CORRYVRECKAN_GLOBAL_MODULE(MODULE_NAME)
FIND_PACKAGE(MUPIX8DAQ REQUIRED)
find_package(Eigen3 REQUIRED)
IF(NOT MUPIX8DAQ_FOUND)
MESSAGE(FATAL_ERROR "Could not find MuPix-telescope. You need to do: \n export MUPIX8DAQ=/path/to/repo")
ENDIF()
INCLUDE_DIRECTORIES(SYSTEM ${MUPIX8DAQ_INCLUDE_DIR})
include_directories(${EIGEN3_INCLUDE_DIR})
# Add source files to library
CORRYVRECKAN_MODULE_SOURCES(${MODULE_NAME}
EventLoaderMuPixTelescope.cpp
# ADD SOURCE FILES HERE...
)
TARGET_LINK_LIBRARIES(${MODULE_NAME} ${MUPIX8DAQ_LIBRARY})
# Provide standard install target
CORRYVRECKAN_MODULE_INSTALL(${MODULE_NAME})
/**
* @file
* @brief Implementation of [EventLoaderMuPixTelescope] module
* Copyright (c) 2019 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
#include "EventLoaderMuPixTelescope.h"
#include "dirent.h"
#include "objects/Cluster.hpp"
#include "objects/Pixel.hpp"
#include "objects/Track.hpp"
using namespace corryvreckan;
// using namespace std;
EventLoaderMuPixTelescope::EventLoaderMuPixTelescope(Configuration config, std::vector<std::shared_ptr<Detector>> detectors)
: Module(std::move(config), std::move(detectors)), m_blockFile(nullptr) {
m_inputDirectory = m_config.getPath("input_directory");
m_runNumber = m_config.get<int>("Run", -1); // meaningless default runnumber
m_isSorted = m_config.get<bool>("is_sorted", false);
m_ts2IsGray = m_config.get<bool>("ts2_is_gray", false);
// We need to check for the config files in case of scans... TBI
}
void EventLoaderMuPixTelescope::initialise() {
for(auto& detector : get_detectors()) {
LOG(DEBUG) << "Initialise for detector " + detector->name();
}
// Need to check if the files do exist
DIR* directory = opendir(m_inputDirectory.c_str());
if(directory == nullptr) {
LOG(ERROR) << "Directory " << m_inputDirectory << " does not exist";
return;
}
// check the entries and if the correct file exists continue - seems to be inefficient
dirent* entry;
bool foundFile = false;
while((entry = readdir(directory))) {
if(entry->d_name == string("telescope_run_001020_mergedFrames.blck")) {
foundFile = true;
break;
}
}
if(!foundFile) {
LOG(ERROR) << "Requested run not existing ";
return;
} else
LOG(INFO) << "File found" << endl;
string file = (m_inputDirectory + "/" + entry->d_name);
LOG(INFO) << "reading " << file;
m_blockFile = new BlockFile(file);
if(!m_blockFile->open_read()) {
LOG(ERROR) << "File cannot be read" << endl;
return;
} else
LOG(STATUS) << "Loaded Reader";
hHitMap = new TH2F("hitMap", "hitMap; column; row", 50, -.5, 49.5, 202, -.5, 201.5);
hPixelToT = new TH1F("pixelToT", "pixelToT; ToT in TS2 clock cycles.; ", 64, 0, 64);
hTimeStamp = new TH1F("pixelTS", "pixelTS; TS in clock cycles; ", 1024, -.5, 1023.5);
}
StatusCode EventLoaderMuPixTelescope::run(std::shared_ptr<Clipboard> clipboard) {
// Loop over all detectors
vector<string> detectors;
for(auto& detector : get_detectors()) {
// Get the detector name
std::string detectorName = detector->name();
detectors.push_back(detectorName);
LOG(DEBUG) << "Detector with name " << detectorName;
}
map<string, Objects*> dataContainers;
TelescopeFrame tf;
if(!m_blockFile->read_next(tf))
return StatusCode::EndRun;
else {
LOG(DEBUG) << "Found " << tf.num_hits() << " in event " << m_eventNumber;
for(uint i = 0; i < tf.num_hits(); ++i) {
RawHit h = tf.get_hit(i);
if(h.tag() == 0x4)
h = tf.get_hit(i, 66);
Pixel* p = new Pixel(detectors.at(h.tag() / 4), h.row(), h.column(), 1, 0, true);
p->setTimestamp(8 * static_cast<double>(((tf.timestamp() >> 2) & 0xFFFFF700) + h.timestamp_raw()));
p->setToT(0);
if(!dataContainers.count(detectors.at(h.tag() / 4)))
dataContainers[detectors.at(h.tag() / 4)] = new Objects();
dataContainers.at(detectors.at(h.tag() / 4))->push_back(p);
hHitMap->Fill(h.column(), h.row());
hTimeStamp->Fill(h.timestamp_raw());
}
}
for(auto d : detectors) {
if(!dataContainers.count(d))
continue;
try {
clipboard->put(d, "pixels", dataContainers[d]);
} catch(ModuleError& e) {
LOG(ERROR) << "Unknown detector ";
}
}
// Increment event counter
m_eventNumber++;
LOG(DEBUG) << "Frame with " << tf.num_hits();
// Return value telling analysis to keep running
return StatusCode::Success;
}
void EventLoaderMuPixTelescope::finalise() {
LOG(DEBUG) << "Analysed " << m_eventNumber << " events";
}
/**
* @file
* @brief Definition of [EventLoaderMuPixTelescope] module
* Copyright (c) 2019 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*
* Contains minimal dummy module to use as a start for the development of your own module
*
* Refer to the User's Manual for more details.
*/
#include <TCanvas.h>
#include <TH1F.h>
#include <TH2F.h>
#include <iostream>
#include "core/module/Module.hpp"
#include "blockfile.hpp"
#include "telescope_frame.hpp"
namespace corryvreckan {
/** @ingroup Modules
* @brief Module to do function
*
* More detailed explanation of module
*/
class EventLoaderMuPixTelescope : public Module {
public:
/**
* @brief Constructor for this unique module
* @param config Configuration object for this module as retrieved from the steering file
* @param detectors Vector of pointers to the detectors
*/
EventLoaderMuPixTelescope(Configuration config, std::vector<std::shared_ptr<Detector>> detectors);
/**
* @brief [Initialise this module]
*/
void initialise();
/**
* @brief [Run the function of this module]
*/
StatusCode run(std::shared_ptr<Clipboard> clipboard);
/**
* @brief [Finalise module]
*/
void finalise();
private:
int m_eventNumber;
std::string m_inputDirectory;
bool m_isSorted;
bool m_ts2IsGray;
int m_runNumber;
BlockFile* m_blockFile;
TelescopeFrame m_tf;
// Histograms
TH2F* hHitMap;
TH1F* hPixelToT;
TH1F* hTimeStamp;
};
} // namespace corryvreckan
# EventLoaderMuPixTelescope
**Maintainer**: Lennart Huth (lennart.huth@desy.de)
**Module Type**: *GLOBAL*
**Status**: work in progress with some hard coded parts - needs polishing
### Description
This module reads in and converts data taken with the MuPix-Telescope.
### Parameters
* `input_directory`: Defines the input file. No default
* `Run`: not in use. Defaults to `-1`
* `is_sorted`: Defines if data recorded is on FPGA timestamp
sorted. Defaults to `false`
* `ts2_is_gray`: Defines if the timestamp is gray encoded or not. Defaults to `false`.
### Plots produced
* 2D histogram of pixel hit positions
* 1D histogram of the pixel timestamps
### Usage
```toml
[EventLoaderMuPixTelescope]
input_directory = "/path/to/file"
Run = -1
is_sorted = false
ts2_is_gray = false
```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment