Giter Club home page Giter Club logo

ptf-analysis's Introduction

PTF Analysis

This is the codebase for analysing the ROOT files produced from the (PMT test facility) PTF. It handles the loading of files, accessing the data (e.g. PMT waveform samples and Phidget readings), fitting of waveforms to produce a tree of fitted parameters, and analyses of the waveform fits (including charge, timing, and efficiency measurements).

Table of Contents

Directory Layout

.
+-- bin/                                # Location of compiled executables
+-- include/                            # Header files
+-- macros/                             # ROOT macros to produce plots from the output of the analysis executables
+-- magnetic-field/                     # Python scripts to process the output of field_to_csv
+-- obj/                                # Location for compiled .o files
+-- ptf_bfield/                         # Standalone analysis of the predicted PTF magnetic field
+-- src/                                # Source files
+-- Makefile                            # Makefile to build executables
+-- field_to_csv.cpp
+-- ptf.config.dat                      # A configuration file that sets analysis options
+-- ptf_analysis.cpp
+-- ptf_charge_analysis.cpp
+-- ptf_field_analysis.cpp
+-- ptf_qe_analysis.cpp
+-- ptf_timing_analysis.cpp
+-- ptf_ttree_analysis.cpp

Installation

To download the repository use:

git clone https://github.com/PMT-Test-Facilities/ptf-analysis

Getting the PTF data

The PTF MIDAS DAQ produces output files. These can be converted to a ROOT TTree with the rootana/libAnalyzer/analyzer_convert_ptf_scan_to_rootTree.cxx script in the ptf-online-converter repository. This step it typically completed automatically on the PTF machine when a scan completes.

The MIDAS files are located here on the PTF machine:
~/online/data/

The ROOT trees are located here on the PTF machine:
~/online/rootfiles/

Usage

To compile the code run make. To build new analyses add them to the Makefile following the example of the existing analyses.

The ptf_analysis executable fits the PMT waveforms and produces a ROOT file that contains a TTree with the fitted parameter values. The fitted parameter values can then be analysed by the ptf_charge_analysis, ptf_qe_analysis and ptf_timing_analysis executables. The command to run the code from the root directory is:
./bin/ptf_analysis.dat filename.root run_number config_file
The run_number argument is to produce an output file with a name specific to the run.

The ptf_ttree_analysis executable is a demonstration of how the TTree produced by ptf_analysis could be accessed. The command to run the code from the root directory is:
./bin/ptf_ttree_analysis.app ptf_analysis.root

The ptf_charge_analysis executable reads the fitted waveforms from ptf_analysis and computes the charge of the events. The command to run the code from the root directory is:
./bin/ptf_charge_analysis.app ptf_analysis.root run_number [T/F/I]
Where the T/F/I is for True to do/not do circle fit to find PMT, I to cut inside circle (default T).
The run_number argument is to produce an output file with a name specific to the run.

The ptf_qe_analysis executable reads the fitted waveforms from ptf_analysis and calculates the detection efficiency for the PMT. The command to run the code from the root directory is:
./bin/ptf_qe_analysis.app ptf_analysis.root run_number
The run_number argument is to produce an output file with a name specific to the run.

The ptf_timing_analysis executable reads the fitted waveforms from ptf_analysis and calculates the timing response for the PMT. The command to run the code from the root directory is:
./bin/ptf_timing_analysis.app ptf_analysis.root run_number
The run_number argument is to produce an output file with a name specific to the run.

The ptf_field_analysis executable reads the data from Phidget04 which is fixed inside the Helmholtz coils and plots its magnetic field values as the scan progresses. This provides an indication of the field stability over the course of a run. The command to run the script from the root directory is:
./bin/ptf_field_analysis.app /data/directory run_number
The run_number argument is to produce an output file with a name specific to the run.

The field_to_csv analysis reads the magnetic field values from the Phidgets and outputs them to a csv file for analysis by the python scripts in the magnetic-field directory.

The mpmt_analysis executable fits the mPMT PMT waveforms and produces a ROOT file that contains a TTree with the fitted parameter values. The fitted parameter values can then be analysed by the further executables. The command to run the code from the root directory is:
./bin/mpmt_analysis.dat filename.root run_number mpmt.config.dat
The run_number argument is to produce an output file with a name specific to the run.

The different classes

These are the classes that are most important to understand.

+-- wrapper               Handles the loading of files and accessing the data
+-- Configuration         Loads options from configuration file
+-- PTFErrorBarAnalysis   For calculating the error bar size to use on the waveforms
+-- PTFAnalysis           For doing analysis of all of the waveforms, and keep track of scan points, stores results in TTree
+-- WaveformFitResult     Structure to hold one waveform fit result
+-- ScanPoint             Holds location of scan point, first entry number in TTree of scan point, and number of waveforms

The wrapper class

It handles loading the files and provides a simple way to access the data. A simple example of how you might use it can be found in wrapper_demo.cpp.

Data Types

Here is a brief overview of the data types you'll use (all in "wrapper.hpp", in namespace PTF):

Gantry (enum Gantry)

enum Gantry {
  Gantry0 = 0,
  Gantry1 = 1
};

Just an enum for which gantry you want to reference.

PMTType (enum PMTType)

enum PMTType {
  Hamamatsu_R3600_PMT = 0,
  PTF_Monitor_PMT = 1,
  PTF_Receiver_PMT = 2,
  mPMT_REV0_PMT = 3,
  mPMT_Monitor_PMT = 4,
  Reference = 5
};

An enum for the PMT type

PMT (struct PMT)

typedef struct PMT {
  int pmt;
  int channel;
  PMTType type;
} PMTChannel;

A structure which maps PMTs to their channel and type. int pmt is the PMT's number, int channel is the digitizer channel used to read the info, and PMTType type is the type of PMT.

Phidget Reading (struct PhidgetReading)

typedef struct PhidgetReading {
  double Bx[10];
  double By[10];
  double Bz[10];
} PhidgetReading;

Data read for the phidget. Mostly you'll probably just want index 0 of each, which is the magnetic field.

Ganty Data (struct GantryData)

typedef struct GantryData {
  double x;
  double y;
  double z;
  double theta;
  double phi;
} GantryData;

Contains the position information for a gantry.

DigitizerModel (enum DigitizerModel)

enum DigitizerModel {
  PTF_CAEN_V1730 = 0,
  mPMT_DIGITIZER = 1
};

An enum for the digitizer type

Digitizer Settings (struct Digitizer)

typedef struct Digitizer {
  DigitizerModel model;
  int samplingRate;
  double fullScaleRange;
  int resolution;
};

A structure to store the digitizer settings. Units are MS/s (mega samples per second) for the sampling rate, Vpp (Voltage peak-to-peak) for the full scale range, and bits for the resolution.

How to use install the wrapper :

This is a simple C++ library for reading the ROOT files produced from the PTF. It handles loading the files and provides a simple way to access the data.

It can be build with make wrapper.o for a debug build (uses -g3 -Og), or with make wrapper.o RELEASE=TRUE for an optimized build (uses -g -O2). You can then link your program with g++ -o myprog myprog.cpp wrapper.o {flags here} -I$(ROOTSYS)/include/root -L$(ROOTSYS)/lib/root -lCore -lHist -lRIO -lTree -lGpad. clang++ works as well, but make sure that ROOT, wrapper.o and your program are all compiled with the same compiler.

#include <vector>

#include "wrapper.hpp"


using namespace std;


int main(void) {
  // decide which channels we'd like
  vector<PTF::PMTChannel> channels = {
    {1, 3} // this is saying we want pmt #1, which is on channel 3.
  };

  // decide which phidgets we'd like to read
  vector<int> phidgets = {1, 3, 4};

  // initialize the wrapper
  auto wrapper = PTF::Wrapper(
    16384, // the maximum number of samples
    34, // the size of one sample
    channels,
    phidgets
  );

  // now we can open our file
  wrapper.openFile("/path/to/file.root");

  cout << "There are " << wrapper.getNumEntries() << " entries." << endl;

  // we can iterate over all the entries

  for (size_t i = 0; i < wrapper.getNumEntries(); i++) {
    wrapper.setCurrentEntry(i);

    // get data from phidget 3
    PhidgetReading phidgetReading = wrapper.getReadingForPhidget(3);

    // get data from gantry 1
    GantryPos gantryData = wrapper.getDataForCurrentEntry(PTF::Gantry1);

    // see how many samples there are for the current entry
    auto numSamples = wrapper.getNumSamples();

    for (size_t sample = 0; sample < numSamples; sample++) {
      // Gets a pointer to the data for PMT 1 for this sample
      // It's an array with the length of one sample, set above, in this case 34.
      double* data = getPmtSample(1, sample);
      // do something with data
    }
  }

  // wrapper is automatically deallocated when it goes out of scope here, and its destructor cleans up memory
}

=======

Methods of PTF::Wrapper

Here are the methods of PTF::Wrapper:

  • Wrapper(size_t maxSamples, size_t sampleSize, const std::vector<PMT>& activePMTs, const std::vector<int>& phidgets, const std::vector<Gantry>& gantries, DigitizerModel digi)
    • Constructs a wrapper object and prepares to read the given PMTs and phidgets.
  • Wrapper(size_t maxSamples, size_t sampleSize, const std::vector<PMT>& activePMTs, const std::vector<int>& phidgets, const std::vector<Gantry>& gantries, DigitizerModel digi, const std::string& fileName, const std::string& treeName = "scan_tree")
    • Constructs a wrapper object like above, but immediately opens a file and loads a scan tree ("scan_tree" by default).
  • void openFile(const std::string& fileName, const std::string& treeName = "scan_tree")
    • Opens a file, as described above.
  • bool isFileOpen() const
    • Returns true if the wrapper currently has a file loaded, false otherwise.
  • void closeFile()
    • Closes the current file, if one is open. Does nothing if there is no file open.
  • int getChannelForPmt(int pmt) const
    • Gets the channel for the given PMT. Returns -1 if it's not found.
  • int getPmtForChannel(int channel) const
    • Does the inverse of the above, also returning -1 if not found.
  • size_t getCurrentEntry() const
    • Gets the current entry. Throws NoFileIsOpen if no file is open.
  • size_t getNumEntries() const
    • Gets the total number of entries. Throws NoFileIsOpen if no file is open.
  • void setCurrentEntry(size_t entry)
    • Sets the current entry. Throws NoFileIsOpen if no file is open, and EntryOutOfRange if the entry is too large.
  • size_t getNumSamples() const
    • Gets the number of samples for the current entry. Throws NoFileIsOpen if no file is open.
  • double* getPmtSample(int pmt, size_t sample) const
    • Returns a pointer to an array of length sampleSize which is the sample for the PMT on the current entry. Throws SampleOutOfRange if the sample is too large, InvalidPMT if the PMT can't be found and NoFileIsOpen if no file is open.
  • int getSampleLength() const
    • Returns sampleSize.
  • GantryData getDataForCurrentEntry(Gantry whichGantry) const
    • Gets gantry position info for a given gantry. Throws if no file is open.
  • PhidgetReading getReadingFOrPhidget(int phidget) const
    • Gets the phidget data for the given phidget and current entry. Throws InvalidPhidget if the phidget wasn't registered, and NoFileIsOpen if no file is open.
  • Digitizer getDigitizerSettings() const
    • Gets the digitizer settings.

ptf-analysis's People

Contributors

thomaslindner avatar yukama18 avatar vgousyleblanc avatar haelshabasy avatar pdeperio avatar angelamoskal avatar ashleygeddes avatar hdastgir avatar hunterm321 avatar luanviko avatar

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.