diff --git a/.containers/Dockerfile.in b/.containers/Dockerfile.in new file mode 100644 index 0000000000000000000000000000000000000000..06567d32b0985cde7c1d20a331ba75bda4ab6522 --- /dev/null +++ b/.containers/Dockerfile.in @@ -0,0 +1,22 @@ +FROM eicweb.phy.anl.gov:4567/containers/image_recipes/root_spack:@CONTAINER_TAG@ + +LABEL maintainer "Sylvester Joosten <sjoosten@anl.gov>" + +RUN cd /tmp \ + && git clone https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/hallac_evio.git \ + && mkdir hallac_evio/build && cd hallac_evio/build \ + && cmake ../. && make -j20 && make install \ + && cd /tmp && rm -rf hallac_evio \ + && git clone https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/analyzer.git \ + && mkdir analyzer/build && cd analyzer/build && git pull && git checkout v1.8.3 \ + && cmake ../. && make -j20 VERBOSE=1 && make install \ + && cd /tmp && rm -rf analyzer + +## 2 layers so we can isolate hcana from the rest of the stack + +RUN cd /tmp \ + && git clone https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/hcana.git \ + && mkdir hcana/build && cd hcana/build \ + && git pull \ + && cmake ../. && make -j20 VERBOSE=1 && make install \ + && cd /tmp && rm -rf hcana diff --git a/.containers/Makefile b/.containers/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d5e8233fff63af2932d816d30bf0cf9c43862c80 --- /dev/null +++ b/.containers/Makefile @@ -0,0 +1,64 @@ +# import config. +# You can change the default config with `make cnf="config_special.env" build` +cnf ?= config.env +include $(cnf) +# exports variables in config.env as environment variables +export $(shell sed 's/=.*//' $(cnf)) + +SHELL = bash + +# grep the version from the mix file +VERSION=$(shell bash version.sh) +TAG_VERSION=$(VERSION) +LONG_TAG=$(VERSION)-$(PUBLISH_TAG) + +# help will output the help for each task +# thanks to https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html +.PHONY: help + +help: ## This help. + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +.DEFAULT_GOAL := help + +# ========================================================================== +# +build: ## build the image + docker build -t $(APP_NAME):$(LONG_TAG) . + +build-nc: ## Build the container without caching (from scratch) + docker build --no-cache -t $(APP_NAME):$(LONG_TAG) . + +# ========================================================================== +# +login: ## Auto login to AWS-ECR unsing aws-cli + @docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} + echo "Login COMPLETE" + +# ========================================================================== +# + +publish: login ## Publish a tagged container to ECR + @echo 'publish $(PUBLISH_TAG) to $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME)' + docker tag $(APP_NAME):$(LONG_TAG) $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME):$(PUBLISH_TAG) + docker push $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME):$(PUBLISH_TAG) + docker rmi $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME):$(PUBLISH_TAG) + +publish-version: login ## Publish the `{version}` taged container to ECR + @echo 'publish $(VERSION) to $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME):$(VERSION)' + docker tag $(APP_NAME):$(LONG_TAG) $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME):$(VERSION) + docker push $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME):$(VERSION) + docker rmi $(REG_NAME)/$(GL_REG_GROUP)/$(APP_NAME):$(VERSION) + +# ========================================================================== +# remove container from registry +unpublish: login + @echo 'removing $(PUBLISH_TAG)' + curl --request DELETE --header "PRIVATE-TOKEN: $(CI_JOB_TOKEN)" "$(REG_API_URL)/$(PUBLISH_TAG)" + +# ========================================================================== +# cleanup docker registry on system used by runner +cleanup: + @echo 'removing $(REG_NAME):$(LONG_TAG)' + docker rmi $(REG_NAME):$(LONG_TAG) + diff --git a/.containers/config.env b/.containers/config.env new file mode 100644 index 0000000000000000000000000000000000000000..79a52b2395efce1644765abfad03b063e2c4aa74 --- /dev/null +++ b/.containers/config.env @@ -0,0 +1,17 @@ +# Port to run the container + +APP_NAME = hcana +REPO_NAME = hcana + +REG_HOST ?= eicweb.phy.anl.gov +REG_NAME ?= eicweb.phy.anl.gov:4567 +REG_PORT ?= 4567 +REG_URL ?= https://$(REG_HOST) + +GL_GROUP = jlab/hallc/analyzer_software +GL_REG_GROUP = jlab/hallc/analyzer_software/hcana +GL_REG_NAME = $(REG_NAME) + +PUBLISH_TAG = $(HCANA_TAG) + +REG_API_URL = $(REG_URL)/api/v4/projects/$(CI_PROJECT_ID)/registry/repositories/49/tags diff --git a/containers/docker/Makefile b/.containers/docker/Makefile similarity index 100% rename from containers/docker/Makefile rename to .containers/docker/Makefile diff --git a/.containers/hcana.def.in b/.containers/hcana.def.in new file mode 100644 index 0000000000000000000000000000000000000000..12ab7e6377bcc4c41f9911595fe6bd51436efa0c --- /dev/null +++ b/.containers/hcana.def.in @@ -0,0 +1,14 @@ +Bootstrap: docker +From: eicweb.phy.anl.gov:4567/jlab/hallc/analyzer_software/hcana:@HCANA_TAG@ + +%help + singularity container for hcana development + +%labels + Maintainer "Whitney Armstrong, Sylvester Joosten" + Version v1-dev + +%post -c /bin/bash + echo " -------------------------------------------------" + echo " ===> Image setup complete" + echo " -------------------------------------------------" diff --git a/containers/singularity/Singularity.broadwell b/.containers/singularity/Singularity.broadwell similarity index 100% rename from containers/singularity/Singularity.broadwell rename to .containers/singularity/Singularity.broadwell diff --git a/.containers/version.sh b/.containers/version.sh new file mode 100644 index 0000000000000000000000000000000000000000..93ef8dc29dfe97a476861893b492f43f49272866 --- /dev/null +++ b/.containers/version.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +cat ../VERSION diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0aaf4ed384f2b72d30361ea0bd8f11481cc309b2..e2978a196d1e894661c130e22d987988ca0ce226 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,84 +1,113 @@ -image: eicweb.phy.anl.gov:4567/containers/image_recipes/root_base:latest +variables: + CONTAINER_TAG: "1.4.0" + +default: + image: eicweb.phy.anl.gov:4567/containers/image_recipes/ubuntu_dind:latest + tags: + - silicon stages: + - config - build - - build_docker - - build_sing_img - - data_replays - - data_tests + - push + - deploy + - cleanup -hcana_build: - stage: build - tags: - - sodium - script: - - ls -lrth /usr/local/bin - - bash bin/compile - -hcana_docker: - stage: build_docker - only: - - tags - tags: - - eic0 docker - script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - cd containers/docker && make release +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_TAG' -hcana_singularity: - tags: - - singularity - stage: build_sing_img - when: manual - dependencies: - - hcana_docker +env: + stage: config script: - - /bin/bash .gitlabci/setup.sh - - mkdir -p build - - pwd - - cp containers/singularity/Singularity Singularity.hcana - - cp Singularity.hcana build/. - - /bin/bash .gitlabci/build.sh Singularity.hcana - - cp Singularity.hcana.simg build/. + - export HCANA_TAG="latest" + - | + if [ "x${CI_PIPELINE_SOURCE}" == "xmerge_request_event" ]; then + export HCANA_TAG="testing-mr-${CI_MERGE_REQUEST_IID}" + fi + - echo "CI HCANA_TAG for this pipeline set to ${HCANA_TAG}" + - echo "HCANA_TAG=$HCANA_TAG" >> hcana.env artifacts: - paths: - - build/Singularity.hcana - - build/Singularity.hcana.simg + reports: + dotenv: hcana.env -elastic_replay: - when: manual - tags: - - eic0 docker - stage: data_replays - dependencies: - - hcana_singularity +docker: + stage: build + needs: + - env script: - - bash tests/replay_elastic_data.sh - artifacts: - paths: - - ROOTfiles/* - - build/Singularity.hcana - - build/Singularity.hcana.simg - + - echo $HCANA_TAG + - ./.gitlabci/configure.sh .containers/Dockerfile.in + - cd .containers + - make build-nc -elastic_test1: - when: manual - tags: - - eic0 docker - stage: data_tests - dependencies: - - elastic_replay +## for now only publish the stable versions to the registry. +## if we change this down the line for some CI-time testing +## make sure to also enable the cleanup job +publish: + stage: push + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + when: manual + - if: '$CI_COMMIT_TAG' + when: manual + needs: + - env + - docker script: - - bash tests/elastic_test.sh + - cd .containers + - | + if [ "x$CI_COMMIT_TAG" != "x" ]; then + make publish publish-version + else + make publish + fi + retry: + max: 2 + when: + - runner_system_failure + - stuck_or_timeout_failure -elastic_test2: - when: manual - tags: - - eic0 docker - stage: data_tests - dependencies: - - elastic_replay +.singularity: + stage: deploy + needs: + - env + - publish script: - - bash tests/elastic_test2.sh + - ./.gitlabci/configure.sh .containers/hcana.def.in + - mkdir -p build + - mv .containers/hcana.def build + - singularity build build/hcana.sif build/hcana.def + retry: + max: 2 + when: + - runner_system_failure + - stuck_or_timeout_failure +singularity:latest: + extends: .singularity + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + when: manual + - if: '$CI_COMMIT_TAG' + when: manual + artifacts: + expire_in: 90 days + paths: + - build/hcana.sif + - build/hcana.def +purge_image: + stage: cleanup + needs: + - env + - publish + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + when: never + script: + - cd .containers + - make cleanup || true + - make unpublish || true diff --git a/.gitlabci/build.sh b/.gitlabci/build.sh old mode 100644 new mode 100755 diff --git a/.gitlabci/configure.sh b/.gitlabci/configure.sh new file mode 100755 index 0000000000000000000000000000000000000000..c59d8a41a734e19c5ba32cc1217f12e281e5a56a --- /dev/null +++ b/.gitlabci/configure.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +## Configure a CI file based on a template file (first and only +## argument to this script). + +## Known variables that will be substituted: +## @CONTAINER_TAG@ - docker tag for the ROOT container +## @HCANA_TAG@ - output tag for the hcana version +## @HCANA_BRANCH@ - hcana git branch for build + +TEMPLATE_FILE=$1 +OUTPUT_FILE=${TEMPLATE_FILE%.*} +HCANA_BRANCH="master" + +if [ -n "${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}" ] ; then + HCANA_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME +fi + +echo "Configuring CI file: ${TEMPLATE_FILE}" +echo "Output will be written to: ${OUTPUT_FILE}" + +sed "s/@CONTAINER_TAG@/$CONTAINER_TAG/g" $TEMPLATE_FILE | \ + sed "s/@HCANA_TAG@/$HCANA_TAG/g" | \ + sed "s/@HCANA_BRANCH@/$HCANA_BRANCH/g" > ${OUTPUT_FILE} + +echo "Done" diff --git a/.gitlabci/setup.sh b/.gitlabci/setup.sh deleted file mode 100644 index 5c9bbe517eb1dc83dc33b142507764e10fd555d1..0000000000000000000000000000000000000000 --- a/.gitlabci/setup.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -apt-get update && apt-get install -y wget git \ - build-essential \ - squashfs-tools \ - libtool \ - autotools-dev \ - libarchive-dev \ - automake \ - autoconf \ - uuid-dev \ - python3 \ - libssl-dev - - -sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers - -# Check Python -echo "Python Version:" -which python -python --version -pip install sregistry[all] -sregistry version - -echo "sregistry Version:" - -# Install Singularity - -cd /tmp && \ - git clone -b vault/release-2.5 https://www.github.com/sylabs/singularity.git - cd singularity && \ - ./autogen.sh && \ - ./configure --prefix=/usr/local && \ - make -j8 && make install diff --git a/.gitlabci/sregistry-gitlab.png b/.gitlabci/sregistry-gitlab.png deleted file mode 100644 index a14e917a20fb32011329af6bc6abd04012acd0d6..0000000000000000000000000000000000000000 Binary files a/.gitlabci/sregistry-gitlab.png and /dev/null differ diff --git a/.gitlabci/sregistry-gitlab.xcf b/.gitlabci/sregistry-gitlab.xcf deleted file mode 100644 index f2742162bfc602f92d3d9c5cd573f29e334e042d..0000000000000000000000000000000000000000 Binary files a/.gitlabci/sregistry-gitlab.xcf and /dev/null differ diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000000000000000000000000000000000..88c5fb891dcf1d1647d2b84bac0630cf9570d213 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.4.0 diff --git a/bin/compile b/bin/compile deleted file mode 100755 index ea6387a783b1d0248b1b727ff622ab78247c79cd..0000000000000000000000000000000000000000 --- a/bin/compile +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -#set -o nounset -set -o errexit -startdir=$(pwd) -export PYTHONPATH=/usr/local/lib:$PYTHONPATH -export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH -export PATH=/usr/local/bin:$PATH -source /usr/local/bin/thisroot.sh -cd /tmp -git clone https://github.com/fmtlib/fmt.git && cd fmt -git checkout 6.2.1 && mkdir /tmp/build && cd /tmp/build -cmake -DBUILD_SHARED_LIBS=TRUE ../fmt -make -j20 install -cd /tmp && rm -r /tmp/build && rm -r /tmp/fmt -cd /tmp -git clone https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/hallac_evio.git -mkdir hallac_evio/build && cd hallac_evio/build -cmake ../. && make -j20 && make install -cd /tmp && rm -rf hallac_evio -cd /tmp -export PYTHONPATH=/usr/local/lib:$PYTHONPATH -export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH -export PATH=/usr/local/bin:$PATH -git clone --depth 1 https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/analyzer.git -mkdir analyzer/build && cd analyzer/build -cmake ../. && make -j20 VERBOSE=1 && make install -cd /tmp && rm -rf analyzer -export PYTHONPATH=/usr/local/lib:$PYTHONPATH -export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH -export PATH=/usr/local/bin:$PATH -source /usr/local/bin/thisroot.sh -cd $startdir -mkdir build && cd build -cmake ../. && make -j20 VERBOSE=1 && make install - diff --git a/containers/docker/Dockerfile b/containers/docker/Dockerfile deleted file mode 100644 index f3a412a9af41a6cb8daffc94fea5cd0826f923d3..0000000000000000000000000000000000000000 --- a/containers/docker/Dockerfile +++ /dev/null @@ -1,53 +0,0 @@ -FROM eicweb.phy.anl.gov:4567/containers/image_recipes/root_base:latest - -LABEL maintainer "Whitney Armstrong <warmstrong@anl.gov>" -# - -RUN ls -lrth /usr/local/lib/lib*.so \ - && export PYTHONPATH=/usr/local/lib:$PYTHONPATH \ - && export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH \ - && export PATH=/usr/local/bin:$PATH \ - && source /usr/local/bin/thisroot.sh \ - && cd /tmp \ - && git clone https://github.com/fmtlib/fmt.git && cd fmt \ - && git checkout 6.2.1 && mkdir /tmp/build && cd /tmp/build \ - && cmake -DBUILD_SHARED_LIBS=TRUE ../fmt \ - && make -j20 install \ - && cd /tmp && rm -r /tmp/build && rm -r /tmp/fmt \ - && cd /tmp \ - && git clone https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/hallac_evio.git \ - && mkdir hallac_evio/build && cd hallac_evio/build \ - && cmake ../. && make -j20 && make install \ - && cd /tmp && rm -rf hallac_evio \ - && cd /tmp \ - && export PYTHONPATH=/usr/local/lib:$PYTHONPATH \ - && export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH \ - && export PATH=/usr/local/bin:$PATH \ - && git clone https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/analyzer.git \ - && mkdir analyzer/build && cd analyzer/build && git pull && git checkout v1.8.2 \ - && cmake ../. && make -j20 VERBOSE=1 && make install \ - && cd /tmp && rm -rf analyzer \ - && export PYTHONPATH=/usr/local/lib:$PYTHONPATH \ - && export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH \ - && export PATH=/usr/local/bin:$PATH \ - && source /usr/local/bin/thisroot.sh \ - && git clone https://eicweb.phy.anl.gov/jlab/hallc/analyzer_software/hcana.git \ - && mkdir hcana/build && cd hcana/build \ - && git pull \ - && cmake ../. && make -j20 VERBOSE=1 && make install \ - && cd /tmp && rm -rf hcana - - -#-DCMAKE_CXX_FLAGS=" -march=haswell -O3 -mfma -malign-data=cacheline -finline-functions " -#&& wget -O- https://root.cern.ch/download/root_v6.14.06.source.tar.gz | tar -zxvf - \ -#&& mv root-6.14.06 root_master \ -#RUN which c++ && ls -lrth /usr/bin/c++ && cd /tmp/builds/root_build && make -j38 VERBOSE=1 && make install \ -# && cd /tmp && rm -rf /tmp/root_master && rm -rf /tmp/builds/root_build - -#RUN useradd -ms /bin/bash -d /opt/user user -#USER user -#WORKDIR /opt/bubble_user - -##CMD ["-c" ] -#ENTRYPOINT ["/bin/bash"] - diff --git a/containers/docker/Dockerfile.broadwell b/containers/docker/Dockerfile.broadwell deleted file mode 100644 index 9185d4528387f17217baf733244bdc6bf2e03a54..0000000000000000000000000000000000000000 --- a/containers/docker/Dockerfile.broadwell +++ /dev/null @@ -1,58 +0,0 @@ -# ROOT base -# -# A container for the latest root -# -FROM whit/image_recipes/ubuntu_base:latest -LABEL maintainer "Whitney Armstrong <warmstrong@anl.gov>" -# - -RUN cd /tmp \ - && wget http://bitbucket.org/eigen/eigen/get/3.3.4.tar.bz2 \ - && tar -xvf 3.3.4.tar.bz2 \ - && cd eigen-* \ - && mkdir build && cd build \ - && cmake ../. -DCMAKE_CXX_FLAGS=" -march=haswell -O3 -mfma -malign-data=cacheline -finline-functions " \ - && make -j10 > /tmp/eigen_build.log && make install - -RUN cd /tmp \ - && git clone --depth=1 https://gitlab.cern.ch/CLHEP/CLHEP.git \ - && mkdir -p builds/clhep_build \ - && cd builds/clhep_build \ - && cmake /tmp/CLHEP/. -DCMAKE_CXX_FLAGS=" -march=haswell -O3 -mfma -malign-data=cacheline -finline-functions "\ - && make -j38 install > /tmp/clhep_build.log \ - && cd /tmp && rm -rf /tmp/CLHEP && rm -rf /tmp/builds/clhep_build - -RUN cd /tmp \ -&& git clone https://github.com/VcDevel/Vc.git \ -&& cd Vc \ -&& git submodule update --init \ -&& mkdir build && cd build \ -&& cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTING=OFF -DTARGET_ARCHITECTURE=broadwell ../. \ -&& make -j30 > /tmp/vc_build.log \ -&& make install - -# Build root from the repo master -RUN cd /tmp \ - && pwd \ - && git clone --depth=1 https://github.com/root-project/root.git root_master \ - && cd /tmp && mkdir -p builds/root_build \ - && cd builds/root_build \ - && cmake ../../root_master/. -Droot7:BOOL=ON -Dcxx17:BOOL=ON -Dfortran:BOOL=ON \ - -Dgdml:BOOL=ON -Dmathmore:BOOL=ON -Dminuit2:BOOL=ON -Dbuiltin_vdt:BOOL=ON -Dbuiltin_veccore:BOOL=ON \ - -Dvc:BOOL=ON -Dbuiltin_vecgeom:BOOL=ON -Dunuran:BOOL=ON \ - && cd /tmp/builds/root_build && make -j38 > /tmp/root_build.log && make install \ - && cd /tmp && rm -rf /tmp/root_master && rm -rf /tmp/builds/root_build - -#-DCMAKE_CXX_FLAGS=" -march=haswell -O3 -mfma -malign-data=cacheline -finline-functions " -#&& wget -O- https://root.cern.ch/download/root_v6.14.06.source.tar.gz | tar -zxvf - \ -#&& mv root-6.14.06 root_master \ -#RUN which c++ && ls -lrth /usr/bin/c++ && cd /tmp/builds/root_build && make -j38 VERBOSE=1 && make install \ -# && cd /tmp && rm -rf /tmp/root_master && rm -rf /tmp/builds/root_build - -#RUN useradd -ms /bin/bash -d /opt/user user -#USER user -#WORKDIR /opt/bubble_user - -##CMD ["-c" ] -#ENTRYPOINT ["/bin/bash"] - diff --git a/containers/docker/README.md b/containers/docker/README.md deleted file mode 100644 index d6337961f1b7287f56f0b92aa3c87994f04abd55..0000000000000000000000000000000000000000 --- a/containers/docker/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Hall A/C Software -================= - - -Images for running containers for all aspects of the SANE experimental -analysis. - -The starting point is a pre-built image for the ROOT libraries. (ubuntu + ROOT) - -Main software libraries: - - - `evio`: Built from https://github.com/whit2333/hallac_evio - - `analyzer`: Hall A analyzer (podd)from https://github.com/whit2333/analyzer - - `hcana`: Hall C analyzer from https://github.com/whit2333/hcana - -These are all built using the super build project `cool_halls` (https://github.com/whit2333/cool_halls) - - diff --git a/containers/docker/config.env b/containers/docker/config.env deleted file mode 100644 index 631951825ad49e88b62bd773e249dd89b9c01ac0..0000000000000000000000000000000000000000 --- a/containers/docker/config.env +++ /dev/null @@ -1,23 +0,0 @@ -# Port to run the container -PORT=4000 - -REG_TOKEN ?= ${CI_IMAGE_BUILD_PAT} -REG_USER ?= whit -REG_NAME ?= eicweb.phy.anl.gov:4567 -REG_HOST ?= eicweb.phy.anl.gov:4567 - -# name of alternate build: -# Dockerfile.$(ALT_NAME) --> $(APP_NAME)_${ALT_NAME} -ALT_NAME ?= broadwell - -APP_NAME = hcana -REPO_NAME = hcana -DH_ORG = hallac -GL_GROUP = jlab/hallc/analyzer_software -GL_REG_GROUP = jlab/hallc/analyzer_software -GL_REG_NAME = hcana -REPO = hcana -TAG_VERSION = latest - - - diff --git a/containers/docker/deploy.env b/containers/docker/deploy.env deleted file mode 100644 index 909aa72672001a5758a7f8c08619c7aa489defa1..0000000000000000000000000000000000000000 --- a/containers/docker/deploy.env +++ /dev/null @@ -1,5 +0,0 @@ -# You have to define the values in {} -#DOCKER_REPO={account-nr}.dkr.ecr.{region}.amazonaws.com -## optional aws-cli options -#AWS_CLI_PROFILE={aws-cli-profile} -#AWS_CLI_REGION={aws-cli-region} diff --git a/containers/docker/usage.sh b/containers/docker/usage.sh deleted file mode 100644 index 0b72b4786a77c190f0247a7f566fc50f93c914d6..0000000000000000000000000000000000000000 --- a/containers/docker/usage.sh +++ /dev/null @@ -1,26 +0,0 @@ -# INSTALL -# - copy the files deploy.env, config.env, version.sh and Makefile to your repo -# - replace the vars in deploy.env -# - define the version script - -# Build the container -make build - -# Build and publish the container -make release - -# Publish a container to AWS-ECR. -# This includes the login to the repo -make publish - -# Run the container -make run - -# Build an run the container -make up - -# Stop the running container -make stop - -# Build the container with differnt config and deploy file -make cnf=another_config.env dpl=another_deploy.env build \ No newline at end of file diff --git a/containers/docker/version.sh b/containers/docker/version.sh deleted file mode 100644 index 504899f94c6af4dcb28d4b7e6017c47614478b23..0000000000000000000000000000000000000000 --- a/containers/docker/version.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -echo "0.1" diff --git a/containers/singularity/Singularity b/containers/singularity/Singularity deleted file mode 100644 index e57ff64c3eeaacf29147da31449d3b5ca9ba7ca3..0000000000000000000000000000000000000000 --- a/containers/singularity/Singularity +++ /dev/null @@ -1,125 +0,0 @@ -Bootstrap: docker -From: eicweb.phy.anl.gov:4567/jlab/hallc/analyzer_software/hcana:latest - -%help - Hall A/C container. - Tools: - - evio : EVIO DAQ data format - - analyzer : Hall A analyzer (podd) - - hcana : Hall C analyzer (hcana) - - root : root version used for the analyzer - - rootls, rootbrowse, root_config - -%labels - Maintainer "Whitney Armstrong, Sylvester Joosten" - Version v1.0 - -%setup -c /bin/bash - export SINGULARITY_SHELL=/bin/bash - -%environment -c /bin/bash - export PYTHONPATH=/usr/local/lib:${PYTHONPATH} - export PATH=/usr/local/bin:${PATH} - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - export ROOT_INCLUDE_PATH=/usr/local/include:/usr/local/include/podd:/usr/local/include/hcana - -%post -c /bin/bash - echo "Hello from post" - echo "Install additional software here" - source /usr/local/bin/thisroot.sh - ## libformat and nlohmann json used heavily in new generation replay scripts - ## libformat - #cd /tmp && git clone https://github.com/fmtlib/fmt.git && cd fmt && \ - # git checkout 5.3.0 && mkdir /tmp/build && cd /tmp/build && \ - # cmake -DBUILD_SHARED_LIBS=TRUE ../fmt && - # make -j4 install && cd /tmp && rm -r /tmp/build && rm -r /tmp/fmt - ### json - -# ======================= -# global -# ======================= - -%runscript - echo "Launching a shell in the Hall A/C singularity container - exec bash - - -# ======================= -# root -# ======================= -%apprun root - root "$@" - -%appenv root - export PYTHONPATH=/usr/local/lib:${PYTHONPATH} - export PATH=/usr/local/bin:${PATH} - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - export ROOT_INCLUDE_PATH=/usr/local/include/podd:/usr/local/include/hcana - -# ======================= -# analyzer -# ======================= -%apprun analyzer - analyzer "$@" - -%appenv analyzer - export PYTHONPATH=/usr/local/lib:${PYTHONPATH} - export PATH=/usr/local/bin:${PATH} - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - export ROOT_INCLUDE_PATH=/usr/local/include/podd:/usr/local/include/hcana - -# ======================= -# hcana -# ======================= -%apphelp hcana - Run the Hall-C analyzer with same root-style arguments. - -%apprun hcana - source /usr/local/bin/thisroot.sh - hcana "$@" - -%appenv hcana - export DB_DIR=DBASE - export PYTHONPATH=/usr/local/lib:${PYTHONPATH} - export PATH=/usr/local/bin:${PATH} - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - export ROOTSYS=/usr/local - export ROOT_INCLUDE_PATH=/usr/local/include - export ROOT_INCLUDE_PATH=/usr/local/include:/usr/local/include/podd:/usr/local/include/hcana - -# ======================= -# root-config -# ======================= -%apprun root_config - root-config "$@" - -%appenv root_config - export PYTHONPATH=/usr/local/lib:${PYTHONPATH} - export PATH=/usr/local/bin:${PATH} - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - export ROOT_INCLUDE_PATH=/usr/local/include/podd:/usr/local/include/hcana - - -# ======================= -# rootbrowse -# ======================= -%apprun rootbrowse - rootbrowse "$@" - -%appenv rootbrowse - export PYTHONPATH=/usr/local/lib:${PYTHONPATH} - export PATH=/usr/local/bin:${PATH} - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - export ROOT_INCLUDE_PATH=/usr/local/include/podd:/usr/local/include/hcana - -# ======================= -# rootls -# ======================= -%apprun rootls - rootls "$@" - -%appenv rootls - export PYTHONPATH=/usr/local/lib:${PYTHONPATH} - export PATH=/usr/local/bin:${PATH} - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - export ROOT_INCLUDE_PATH=/usr/local/include/podd:/usr/local/include/hcana diff --git a/podd b/podd index ecff1455f2868eee65295d4aa6e772eefb2dd941..355b3ce629f8f47f107e2a0fcfa7ee55b3463b6c 160000 --- a/podd +++ b/podd @@ -1 +1 @@ -Subproject commit ecff1455f2868eee65295d4aa6e772eefb2dd941 +Subproject commit 355b3ce629f8f47f107e2a0fcfa7ee55b3463b6c diff --git a/src/THcHelicityScaler.cxx b/src/THcHelicityScaler.cxx index 13423a6cc88269cffa2c8c9ec9220d9939e29d19..8b6ff54ec2003422908f742b0d20fcdf9c35c47a 100644 --- a/src/THcHelicityScaler.cxx +++ b/src/THcHelicityScaler.cxx @@ -5,29 +5,36 @@ ~~~ ~~~ - THcHelcityScaler *hhelscaler = new THcHelicityScaler("H","HC helicity scalers"); - // hscaler->SetDebugFile("HHelScaler.txt"); - hhelscaler->SetROC(8); // 5 for HMS defaults to 8 for SHMS - hhelscaler->SetBankID(0x9801); // Will default to this - gHaEvtHandlers->Add (hhelscaler); + THcHelcityScaler *phelscaler = new THcHelicityScaler("P","HC helicity scalers"); + phelscaler->SetDebugFile("PHelScaler.txt"); + phelscaler->SetROC(8); // 5 for HMS defaults to 8 for SHMS + phelscaler->SetBankID(9801); // Will default to this + gHaEvtHandlers->Add (phelscaler); ~~~ -\author +\authors: S. A. Wood (saw@jlab.org) + C. Yero (cyero@jlab.org) + */ + +#include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> -#include <iomanip> #include <iostream> #include <iterator> +#include <map> #include <sstream> -#include <unordered_map> #include "TMath.h" #include "TNamed.h" #include "TROOT.h" #include "TString.h" +#include "fmt/core.h" +#include "nlohmann/json.hpp" //#include "THaEvtTypeHandler.h" +#include "GenScaler.h" +#include "Scaler3801.h" #include "THaCodaData.h" #include "THaEvData.h" #include "THaGlobals.h" @@ -36,13 +43,9 @@ #include "THcHelicityScaler.h" #include "THcParmList.h" - #include "Helper.h" #include "THaVarList.h" #include "VarDef.h" -#include "nlohmann/json.hpp" - -using nlohmann::json; using namespace std; using namespace Decoder; @@ -56,16 +59,18 @@ static const UInt_t ICUT = 6; static const UInt_t MAXCHAN = 32; static const UInt_t defaultDT = 4; -// Compute Charge Asymmetries -static std::unordered_map<std::string, Int_t> bcmindex = { - {"BCM1", 0}, {"BCM2", 2}, {"Unser", 6}, {"BCM4A", 10}, {"BCM4B", 4}, {"BCM4C", 12}, {"1MHz", 8}, -}; -static const Int_t clockindex = 8; -static const Double_t clockfreq = 1000000.0; - THcHelicityScaler::THcHelicityScaler(const char* name, const char* description) : hcana::ConfigLogging<THaEvtTypeHandler>(name, description), fBankID(9801), - fUseFirstEvent(kTRUE), fDelayedType(-1) { + fUseFirstEvent(kTRUE), fDelayedType(-1), fBCM_Gain(0), fBCM_Offset(0), fBCM_SatOffset(0), + fBCM_SatQuadratic(0), fBCM_delta_charge(0), evcount(0), evcountR(0.0), ifound(0), + fNormIdx(-1), fNormSlot(-1), dvars(0), dvarsFirst(0), fScalerTree(0), fOnlyBanks(kFALSE), + fClockChan(-1), fLastClock(0) { + + fRocSet.clear(); + fModuleSet.clear(); + + //--------------------------------------------------------------------------- + fROC = -1; fNScalerChannels = 32; @@ -75,136 +80,229 @@ THcHelicityScaler::THcHelicityScaler(const char* name, const char* description) AddEvtType(5); AddEvtType(6); AddEvtType(7); + AddEvtType(129); SetDelayedType(129); } THcHelicityScaler::~THcHelicityScaler() { - for (vector<UInt_t*>::iterator it = fDelayedEvents.begin(); it != fDelayedEvents.end(); ++it) + + if (!TROOT::Initialized()) { + delete fScalerTree; + } + Podd::DeleteContainer(scalers); + Podd::DeleteContainer(scalerloc); + + for (auto it = fDelayedEvents.begin(); it != fDelayedEvents.end(); ++it) delete[] * it; fDelayedEvents.clear(); } Int_t THcHelicityScaler::End(THaRunBase* runbase) { + // Process any delayed events in order received - const static char* const here = "THcHelicityScaler::End"; - _param_logger->info("{} Analyzing {} delayed helicity scaler events", here, - fDelayedEvents.size()); - for (auto it = fDelayedEvents.begin(); it != fDelayedEvents.end(); ++it) { + for (std::vector<UInt_t*>::iterator it = fDelayedEvents.begin(); it != fDelayedEvents.end(); + ++it) { UInt_t* rdata = *it; AnalyzeBuffer(rdata); } + evNumberR = -1; - for (auto it = fDelayedEvents.begin(); it != fDelayedEvents.end(); ++it) { + for (vector<UInt_t*>::iterator it = fDelayedEvents.begin(); it != fDelayedEvents.end(); ++it) delete[] * it; - } fDelayedEvents.clear(); - // cout << " -- Helicity Scalers -- " << endl; + // Write the helicity variables to scaler tree + if (fScalerTree) { + fScalerTree->Write(); + } + + // Compute Scaler Asymmetries + /* + for(Int_t i=0;i<fNScalerChannels;i++) { + if(fScalerSums[i]>0.5) { + fScalAsymmetry[i] = (fHScalers[0][i]-fHScalers[1][i])/fScalerSums[i]; + fScalAsymmetryError[i] = 2*TMath::Sqrt(fHScalers[0][i]*fHScalers[1][i] + *fScalerSums[i]) + /(fScalerSums[i]*fScalerSums[i]); + } else { + fScalAsymmetry[i] = 0.0; + fScalAsymmetryError[i] = 0.0; + } + + } + */ + + //------Compute Time Asymmetries------- + + // C.Y. 12/15/2020 Time Asymmetry / Error Calculations (with scaler_current cut) + + if (fQuartetCount <= 1) { + fTimeAsymmetry = -1000.; + fTimeAsymmetryError = 0.0; + } else { + fTimeAsymmetry = fTimeAsymSum / fQuartetCount; // normalize asymmetry to total number of + // quartets + if (fTimeAsymSum2 >= fQuartetCount * TMath::Power(fTimeAsymmetry, 2)) { + fTimeAsymmetryError = + TMath::Sqrt((fTimeAsymSum2 - fQuartetCount * TMath::Power(fTimeAsymmetry, 2)) / + (fQuartetCount * (fQuartetCount - 1))); + } else { + fTimeAsymmetryError = 0.0; + } + } + + //------Compute Scaler Asymmetries------- + + // C.Y. 12/15/2020 Scaler Asymmetry / Error Calculations (with scaler_current cut) + for (Int_t i = 0; i < fNScalerChannels; i++) { - if (fScalerSums[i] > 0.5) { - fAsymmetry[i] = (fHScalers[0][i] - fHScalers[1][i]) / fScalerSums[i]; - fAsymmetryError[i] = 2 * TMath::Sqrt(fHScalers[0][i] * fHScalers[1][i] * fScalerSums[i]) / - (fScalerSums[i] * fScalerSums[i]); + + if (fQuartetCount <= 1) { + fScalAsymmetry[i] = -1000.; + fScalAsymmetryError[i] = 0.0; } else { - fAsymmetry[i] = 0.0; - fAsymmetryError[i] = 0.0; + fScalAsymmetry[i] = + fScalAsymSum[i] / fQuartetCount; // normalize asymmetry to total number of quartets + if (fScalAsymSum2[i] >= fQuartetCount * TMath::Power(fScalAsymmetry[i], 2)) { + fScalAsymmetryError[i] = + TMath::Sqrt((fScalAsymSum2[i] - fQuartetCount * TMath::Power(fScalAsymmetry[i], 2)) / + (fQuartetCount * (fQuartetCount - 1))); + } else { + fScalAsymmetryError[i] = 0.0; + } } - // printf("%2d %12.0f %12.0f %12.0f %12.8f\n",i,fScalerSums[i], - // fHScalers[0][i],fHScalers[1][i], - // fAsymmetry[i]); } - // cout << " ---------------------- " << endl; + // json dump of helicity charge info - json j_helicity; - int run_number = runbase->GetNumber(); + const int run_number = runbase->GetNumber(); j_helicity["run_number"] = run_number; - // Compute Charge Asymmetries + //------Compute Charge Asymmetries------- + + // C.Y. 12/14/2020 Charge Asymmetry / Error Calculations (with scaler_current cut) + + // Set the helicity scaler module channels for each BCM std::map<std::string, Int_t> bcmindex; - bcmindex["BCM1"] = 0; - bcmindex["BCM2"] = 2; - // bcmindex["Unser"] = 6; - bcmindex["BCM4A"] = 10; - bcmindex["BCM4B"] = 4; - bcmindex["BCM4C"] = 12; - // bcmindex["1MHz"] = 8; - Int_t clockindex = 8; - Double_t clockfreq = 1000000.0; - - Double_t pclock = fHScalers[0][clockindex]; - Double_t mclock = fHScalers[1][clockindex]; - _param_logger->info("{}: -- Beam Charge Asymmetries -- ", here); + bcmindex["BCM1_Hel.scal"] = 0; + bcmindex["BCM2_Hel.scal"] = 2; + bcmindex["Unser_Hel.scal"] = 6; + bcmindex["BCM4A_Hel.scal"] = 10; + bcmindex["BCM4B_Hel.scal"] = 4; + bcmindex["BCM4C_Hel.scal"] = 12; + // bcmindex["1MHz_Hel.scal"] = 8; + + // cout << endl << "---------------------- Beam Charge Asymmetries ---------------------- " << + // endl; cout << " BCM Total Charge Beam ON Beam ON Asymmetry" << + // endl; cout << " Name Charge Asymmetry Charge Asymmetry Error" << + // endl; + for (Int_t i = 0; i < fNumBCMs; i++) { - if (bcmindex.find(fBCM_Name[i]) != bcmindex.end()) { - Int_t index = bcmindex[fBCM_Name[i]]; - Double_t pcounts = fHScalers[0][index]; - Double_t mcounts = fHScalers[1][index]; - // cout << index << " " << fBCM_Name[i] << " " << pcounts << " " << mcounts - // << " " << fBCM_Gain[i] - // << " " << fBCM_Offset[i] << endl; - Double_t pcharge = (pcounts - (pclock / clockfreq) * fBCM_Offset[i]) / fBCM_Gain[i]; - Double_t mcharge = (mcounts - (mclock / clockfreq) * fBCM_Offset[i]) / fBCM_Gain[i]; - fCharge[i] = pcharge + mcharge; - if (fCharge[i] > 0.0) { - fChargeAsymmetry[i] = (pcharge - mcharge) / fCharge[i]; + + if (fQuartetCount <= 1) { + fChargeAsymmetry[i] = -1000.; + fChargeAsymmetryError[i] = 0.0; + } else { + fChargeAsymmetry[i] = + fChargeAsymSum[i] / fQuartetCount; // normalize charge asymmetry to total number of + // quartets (as the sum is for every quartet) + + if (fChargeAsymSum2[i] >= fQuartetCount * TMath::Power(fChargeAsymmetry[i], 2)) { + fChargeAsymmetryError[i] = TMath::Sqrt( + (fChargeAsymSum2[i] - fQuartetCount * TMath::Power(fChargeAsymmetry[i], 2)) / + (fQuartetCount * (fQuartetCount - 1))); } else { - fChargeAsymmetry[i] = 0.0; + fChargeAsymmetryError[i] = 0.0; } - _param_logger->info("{:10} {:12.2f} uC {:12.2f} ppm", fBCM_Name[i], fCharge[i], - fChargeAsymmetry[i] * 1e6); - j_helicity[fBCM_Name[i]] = {{"charge", fCharge[i]}, - {"charge_asymmetry", fChargeAsymmetry[i]}}; } - } + j_helicity[fBCM_Name[i]] = {{"charge", fChargeSum[i]}, + {"charge_asymmetry", fChargeAsymmetry[i]}, + {"charge_asymmetry_error", fChargeAsymmetryError}}; - fTime = (pclock + mclock) / clockfreq; - if (pclock + mclock > 0) { - fTimeAsymmetry = (pclock - mclock) / (pclock + mclock); - } else { - fTimeAsymmetry = 0.0; + // printf("%6s %12.2f %12.8f %12.2f %12.8f %12.8f\n",fBCM_Name[i].c_str(),fCharge[i], + // fChargeAsymmetry[i],fChargeSum[i],asy,asyerr); } - j_helicity["clock"] = {{"time", fTime}, {"time_asymmetry", fTimeAsymmetry}}; - _param_logger->info("{:10} {:12.2f} uC {:12.8f} ppm", "TIME(s)", fTime, fTimeAsymmetry); + + // Compute +/- helicity Times (no BCM cut) + Double_t pclock = fHScalers[0][fClockChan]; + Double_t mclock = fHScalers[1][fClockChan]; + + fTimePlus = pclock / fClockFreq; + fTimeMinus = mclock / fClockFreq; + fTime = (pclock + mclock) / fClockFreq; + // if(pclock+mclock>0) { + // fTimeAsymmetry = (pclock-mclock)/(pclock+mclock); + //} else { + // fTimeAsymmetry = 0.0; + //} + // printf("TIME(s)%12.2f %12.8f %12.2f\n",fTime, fTimeAsymmetry, fTimeSum); + j_helicity["clock"] = {{"time", fTime}, + {"time_asymmetry", fTimeAsymmetry}, + {"time_asymmetry_error", fTimeAsymmetryError}}; + + // Compute Helicity Trigger Asymmetries (no BCM cut) if (fNTriggersPlus + fNTriggersMinus > 0) { fTriggerAsymmetry = ((Double_t)(fNTriggersPlus - fNTriggersMinus)) / (fNTriggersPlus + fNTriggersMinus); } else { fTriggerAsymmetry = 0.0; } - j_helicity["triggers"] = {{"N_triggers", fTime}, {"trigger_asymmetry", fTriggerAsymmetry}}; - _param_logger->info("{}: -- Beam Charge Asymmetries End --", here); + j_helicity["triggers"] = {{"N_triggers", fNTriggersPlus + fNTriggersMinus}, + {"triggers_asymmetry", fTriggerAsymmetry}}; - { - std::ofstream json_output_file(fmt::format("hel_scalers_{}.json", run_number)); - json_output_file << std::setw(4) << j_helicity << "\n"; - } + // write output to return 0; } Int_t THcHelicityScaler::ReadDatabase(const TDatime& date) { - char prefix[2]; - prefix[0] = 'g'; - prefix[1] = '\0'; - fNumBCMs = 0; - string bcm_namelist; - DBRequest list[] = { - {"NumBCMs", &fNumBCMs, kInt, 0, 1}, {"BCM_Names", &bcm_namelist, kString}, {0}}; + char prefix[2]; + prefix[0] = 'g'; + prefix[1] = '\0'; + fNumBCMs = 0; + DBRequest list[] = {{"NumBCMs", &fNumBCMs, kInt, 0, 1}, {0}}; gHcParms->LoadParmValues((DBRequest*)&list, prefix); + if (fNumBCMs > 0) { fBCM_Gain.resize(fNumBCMs); fBCM_Offset.resize(fNumBCMs); + fBCM_SatOffset.resize(fNumBCMs); + fBCM_SatQuadratic.resize(fNumBCMs); + fBCM_delta_charge.resize(fNumBCMs); + + string bcm_namelist; DBRequest list2[] = {{"BCM_Gain", &fBCM_Gain[0], kDouble, (UInt_t)fNumBCMs}, {"BCM_Offset", &fBCM_Offset[0], kDouble, (UInt_t)fNumBCMs}, + {"BCM_SatQuadratic", &fBCM_SatQuadratic[0], kDouble, (UInt_t)fNumBCMs, 1}, + {"BCM_SatOffset", &fBCM_SatOffset[0], kDouble, (UInt_t)fNumBCMs, 1}, + {"BCM_Names", &bcm_namelist, kString}, + {"BCM_Current_threshold", &fbcm_Current_Threshold, kDouble, 0, 1}, + {"BCM_Current_threshold_index", &fbcm_Current_Threshold_Index, kInt, 0, 1}, {0}}; + + fbcm_Current_Threshold = 0.0; + fbcm_Current_Threshold_Index = 0; + for (Int_t i = 0; i < fNumBCMs; i++) { + fBCM_SatOffset[i] = 0.; + fBCM_SatQuadratic[i] = 0.; + } gHcParms->LoadParmValues((DBRequest*)&list2, prefix); - fBCM_Name = vsplit(bcm_namelist); + vector<string> bcm_names = vsplit(bcm_namelist); + for (Int_t i = 0; i < fNumBCMs; i++) { + fBCM_Name.push_back(bcm_names[i] + "_Hel.scal"); + fBCM_delta_charge[i] = 0.; + } } + fTotalTime = 0.; + fPrevTotalTime = 0.; + fDeltaTime = -1.; + return kOK; } + void THcHelicityScaler::SetDelayedType(int evtype) { + /** * \brief Delay analysis of this event type to end. * @@ -218,6 +316,10 @@ void THcHelicityScaler::SetDelayedType(int evtype) { Int_t THcHelicityScaler::Analyze(THaEvData* evdata) { + // C.Y. | THcScalerEvtHandler::Analyze() uses this flag (which is forced to be 1), + // but as to why, it is beyond me. For consistency, I have also used it here. + Int_t lfirst = 1; + if (!IsMyEvent(evdata->GetEvType())) return -1; @@ -227,30 +329,84 @@ Int_t THcHelicityScaler::Analyze(THaEvData* evdata) { EvDump(evdata); } + if (lfirst && !fScalerTree) { + + lfirst = 0; + + // Assign a name to the helicity scaler tree + TString sname1 = "TSHel"; + TString sname2 = sname1 + fName; + TString sname3 = fName + " Scaler Data"; + + if (fDebugFile) { + *fDebugFile << "\nAnalyze 1st time for fName = " << fName << endl; + *fDebugFile << sname2 << " " << sname3 << endl; + } + + // Create Scaler Tree + fScalerTree = new TTree(sname2.Data(), sname3.Data()); + fScalerTree->SetAutoSave(200000000); + + TString name, tinfo; + + name = "evcount"; + tinfo = name + "/D"; + fScalerTree->Branch(name.Data(), &evcountR, tinfo.Data(), 4000); + + name = "evNumber"; + tinfo = name + "/D"; + fScalerTree->Branch(name.Data(), &evNumberR, tinfo.Data(), 4000); + + // C.Y. 12/02/2020 Added actual helicity to be stored in scaler tree + name = "actualHelicity"; + tinfo = name + "/D"; + fScalerTree->Branch(name.Data(), &actualHelicityR, tinfo.Data(), 4000); + + // C.Y. 12/09/2020 Added quartetphase to be stored in scaler tree + name = "quartetPhase"; + tinfo = name + "/D"; + fScalerTree->Branch(name.Data(), &quartetphaseR, tinfo.Data(), 4000); + + for (size_t i = 0; i < scalerloc.size(); i++) { + name = scalerloc[i]->name; + tinfo = name + "/D"; + fScalerTree->Branch(name.Data(), &dvars[i], tinfo.Data(), 4000); + } + } + UInt_t* rdata = (UInt_t*)evdata->GetRawDataBuffer(); if (evdata->GetEvType() == fDelayedType) { // Save this event for processing later - Int_t evlen = evdata->GetEvLength(); + Int_t evlen = evdata->GetEvLength(); + UInt_t* datacopy = new UInt_t[evlen]; fDelayedEvents.push_back(datacopy); memcpy(datacopy, rdata, evlen * sizeof(UInt_t)); return 1; - } else { // A normal event + } + + else { // A normal event if (fDebugFile) *fDebugFile << "\n\nTHcHelicityScaler :: Debugging event type " << dec << evdata->GetEvType() << " event num = " << evdata->GetEvNum() << endl << endl; - evNumber = evdata->GetEvNum(); + evNumber = evdata->GetEvNum(); + evNumberR = evNumber; + Int_t ret; if ((ret = AnalyzeBuffer(rdata))) { - // + if (fDebugFile) + *fDebugFile << "scaler tree ptr 1 " << fScalerTree << endl; + if (fDebugFile) + *fDebugFile << "ret = " << ret << endl; } + return ret; } } Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { - fNTrigsInBuf = 0; - const static char* const here = "THcHelicityScaler::AnalyzeBuffer"; + + fNTrigsInBuf = 0; // Parse the data, load local data arrays. UInt_t* p = (UInt_t*)rdata; @@ -260,6 +416,7 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { Int_t evlen = *p + 1; Int_t ifound = 0; + while (p < plast) { Int_t banklen = *p; p++; // point to header @@ -273,8 +430,8 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { if (fDebugFile) *fDebugFile << "ROC: " << roc << " " << evlen << " " << *(p - 1) << hex << " " << *p << dec << endl; - // cout << "ROC: " << roc << " " << evlen << " " << *(p-1) << hex << " " << - // *p << dec << endl; + // cout << "ROC: " << roc << " " << evlen << " " << *(p-1) << hex << " " << *p << dec << + // endl; if (roc != fROC) { // Not a ROC with helicity scaler p += *(p - 1) - 1; // Skip to next ROC } @@ -289,9 +446,9 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { // At any point in the bank where the word is not a matching // header, we stop. UInt_t tag = (*p >> 16) & 0xffff; // Bank ID (ROC #) - // UInt_t num = (*p) & 0xff; - UInt_t* pnext = p + banklen; // Next bank - p++; // First data word + // UInt_t num = (*p) & 0xff; + UInt_t* pnext = p + banklen; // Next bank + p++; // First data word // If the bank is not a helicity scaler bank // or it is not one of the ROC containing helcity scaler data // skip to the next bank @@ -299,7 +456,7 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { if (tag != fBankID) { p = pnext; // Fall through to end of the above else if - // cout << " Skipping to next bank" << endl; + // cout << " Skipping to next bank" << endl; } else { // This is a helicity scaler bank @@ -307,15 +464,17 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { Int_t nevents = (banklen - 2) / fNScalerChannels; // cout << "# of helicity events in bank:" << " " << nevents << endl; if (nevents > 100) { - _param_logger->error("{}: Error! Beam off for too long.", here); + cout << "Error! Beam off for too long" << endl; } fNTrigsInBuf = 0; + // Save helcitiy and quad info for THcHelicity for (Int_t iev = 0; iev < nevents; iev++) { // find number of helicity events in each bank Int_t index = fNScalerChannels * iev + 1; + + // C.Y. 11/26/2020 This methods extracts the raw helicity information AnalyzeHelicityScaler(p + index); - // cout << "H: " << evNumber << endl; } } } @@ -325,6 +484,7 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { if (fDebugFile) { *fDebugFile << "Scaler Header: " << hex << *p << dec; } + if (nskip == 0) { if (fDebugFile) { *fDebugFile << endl; @@ -351,16 +511,18 @@ Int_t THcHelicityScaler::AnalyzeBuffer(UInt_t* rdata) { } Int_t THcHelicityScaler::AnalyzeHelicityScaler(UInt_t* p) { - const static char* const here = "THcHelicityScaler::AnalyzeHelicityScaler"; - Int_t hbits = (p[0] >> 30) & 0x3; // quartet and helcity bits in scaler word - Bool_t isquartet = (hbits & 2) != 0; - Int_t ispos = hbits & 1; - Int_t actualhelicity = 0; - fHelicityHistory[fNTrigsInBuf] = hbits; + const static char* const here = "THcHelicityScaler::AnalyzeHelicityScaler"; + + Int_t hbits = (p[0] >> 30) & 0x3; // quartet and helcity bits in scaler word + Bool_t isquartet = (hbits & 2) != 0; + Int_t ispos = hbits & 1; + Int_t actualhelicity = 0; + fHelicityHistory[fNTrigsInBuf] = hbits; fNTrigsInBuf++; fNTriggers++; Int_t quartetphase = (fNTriggers - fFirstCycle) % 4; + if (fFirstCycle >= -10) { if (quartetphase == 0) { Int_t predicted = RanBit30(fRingSeed_reported); @@ -387,8 +549,7 @@ Int_t THcHelicityScaler::AnalyzeHelicityScaler(UInt_t* p) { if (isquartet) { // Helicity and quartet signal for next set of scalers fFirstCycle = fNTriggers - 3; quartetphase = (fNTriggers - fFirstCycle) % 4; - //// Helicity at start of quartet is same as last of quartet, so we can start filling the - /// seed + // Helicity at start of quartet is same as last of quartet, so we can start filling the seed fRingSeed_reported = ((fRingSeed_reported << 1) | ispos) & 0x3FFFFFFF; fNBits++; if (fNBits == 30) { @@ -412,6 +573,7 @@ Int_t THcHelicityScaler::AnalyzeHelicityScaler(UInt_t* p) { actualhelicity = -actualhelicity; } } + quartetphase = (quartetphase + 1) % 4; #else actualhelicity = (fRingSeed_actual & 1) ? +1 : -1; if (quartetphase == 1 || quartetphase == 2) { @@ -422,21 +584,442 @@ Int_t THcHelicityScaler::AnalyzeHelicityScaler(UInt_t* p) { fRingSeed_actual = 0; } + // C.Y. 12/09/2020 : Pass quartet phase to scaler tree varable + quartetphaseR = quartetphase; + + // C.Y. 11/26/2020 The block of code below is used to extract the helicity information from each + // channel of the helicity scaler onto a variable to be stored in the scaler tree. For each + // channel, each helicity state (+, -, or undefined) is stored in a single varibale. Each helicity + // state is tagged to the corresponding scaler read via 'actualHelicityR' which is stored below.. + + // C.Y. Assign actual helicity value to a variable to be written to tree (the value may be (0, + // +hel (+1), or -hel(-1)) Where actualhelicity=0 is NOT the MPS. It is zero when the actual + // helicity has not been determined. + actualHelicityR = actualhelicity; + + // C.Y. 11/26/2020 Loop over all 32 scaler channels for a specific helicity scaler module (SIS + // 3801) + for (Int_t i = 0; i < fNScalerChannels; i++) { + + // C.Y. 11/26/2020 the count expression below gets the scaler raw helicity information (+, -, or + // MPS helicity states) for the ith channel + Int_t count = p[i] & 0xFFFFFF; // Bottom 24 bits equivalent of scalers->Decode() + fScalerChan[i] = + count; // pass the helicity raw information to each helicity scaler channel array element + } + + // C.Y. 11/26/2020 The block of code below is used to get a cumulative sum of +/- helicity used + // for calculation of the cumulative beam charge asymmetry and other quantities in the ::End() + // method if (actualhelicity != 0) { + + // index=0 (+ helicity), index=1 (- helicity) Int_t hindex = (actualhelicity > 0) ? 0 : 1; + + // C.Y. 11/24/2020 increment the counter for either '+' or '-' helicity states (actualhelicity > 0) ? (fNTriggersPlus++) : (fNTriggersMinus++); + + // C.Y. 11/24/2020 Loop over all 32 scaler channels for a specific helicity scaler module (SIS + // 3801) for (Int_t i = 0; i < fNScalerChannels; i++) { - Int_t count = p[i] & 0xFFFFFF; // Bottom 24 bits + + Int_t count = p[i] & 0xFFFFFF; // Bottom 24 bits equivalent of scalers->Decode() + + // Increment either the '+' (hindex=0) or '-' (hindex=1) helicity counts for each [i] scaler + // channel channel of a given module fHScalers[hindex][i] += count; fScalerSums[i] += count; } } + + // Set the helicity scaler clock to define the time + fDeltaTime = + fScalerChan[fClockChan] / + fClockFreq; // total clock counts / clock_frequency (1MHz) for a specific scaler read interval + fTotalTime = fPrevTotalTime + fDeltaTime; // cumulative scaler time + + if (fDeltaTime == 0) { + _param_logger->error("{}: ******************* Severe Warning ****************************", + here); + _param_logger->error("{}: In THcHelicityScaler have found fDeltaTime is zero !!", here); + _param_logger->error("{}: ******************* Alert DAQ experts ***************************", + here); + if (fDebugFile) + *fDebugFile << " In THcHelicityScaler have found fDeltaTime is zero !! " << endl; + } + + fPrevTotalTime = + fTotalTime; // set the current total time to the previous time for the upcoming read + + // C.Y. Nov 27, 2020 : (below) code to write the helicity raw data to a variable + // and map the variable to the scaler location + + Double_t scal_current = 0; + // Loop over each scaler variable from the map + for (size_t i = 0; i < scalerloc.size(); i++) { + size_t ivar = scalerloc[i]->ivar; + size_t idx = scalerloc[i]->index; + size_t ichan = scalerloc[i]->ichan; + + // ANALYZE 1ST SCALER READ SEPARATE (There is no previous read before this one) + if (evcount == 0) { + + // Loop over the scaler variable (ivar), helicity slot (idx), and slot channel (ichan) --> + // idx=0 (only one helicity module per spectrometer arm) + if ((ivar < scalerloc.size()) && (idx < scalers.size()) && (ichan < MAXCHAN)) { + + // If fUseFirstEvent=kTRUE (do not skip 1st read) + if (fUseFirstEvent) { + + // Write scaler counts + if (scalerloc[ivar]->ikind == ICOUNT) { + dvars[ivar] = fScalerChan[ichan]; + dvarsFirst[ivar] = 0.0; + } + + // Write scaler time + if (scalerloc[ivar]->ikind == ITIME) { + dvars[ivar] = fDeltaTime; + dvarsFirst[ivar] = 0.0; + } + + // Write scaler rate + if (scalerloc[ivar]->ikind == IRATE) { + dvars[ivar] = (fScalerChan[ichan]) / fDeltaTime; + dvarsFirst[ivar] = 0.0; + } + + // Write either scaler current or scaler charge + if (scalerloc[ivar]->ikind == ICURRENT || scalerloc[ivar]->ikind == ICHARGE) { + + // Get BCM index + Int_t bcm_ind = -1; + for (Int_t itemp = 0; itemp < fNumBCMs; itemp++) { + size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp])); + if (match != string::npos) { + bcm_ind = itemp; + } + } + + // Calculate and write scaler current + if (scalerloc[ivar]->ikind == ICURRENT) { + + // set default to zero + dvars[ivar] = 0.; + // Check bcm index and calculate current in a temporary placeholder, "cur_temp" + if (bcm_ind != -1) { + Double_t cur_temp = + ((fScalerChan[ichan]) / fDeltaTime - fBCM_Offset[bcm_ind]) / fBCM_Gain[bcm_ind]; + cur_temp = cur_temp + fBCM_SatQuadratic[bcm_ind] * + TMath::Max(cur_temp - fBCM_SatOffset[i], 0.0); + // Assign the calculated scaler current to dvars + dvars[ivar] = cur_temp; + } + // Check which bcm index to place a bcm current threshold cut later on. Assign the the + // beam current read to "scal_current" for later use. + if (bcm_ind == fbcm_Current_Threshold_Index) { + scal_current = dvars[ivar]; + } + } + + // Calculate andd write scaler charge + if (scalerloc[ivar]->ikind == ICHARGE) { + // Check bcm index and calculate current in a temporary placeholder, "cur_temp", to + // determine the charge later on. + if (bcm_ind != -1) { + Double_t cur_temp = + ((fScalerChan[ichan]) / fDeltaTime - fBCM_Offset[bcm_ind]) / fBCM_Gain[bcm_ind]; + cur_temp = + cur_temp + + fBCM_SatQuadratic[bcm_ind] * + TMath::Power(TMath::Max(cur_temp - fBCM_SatOffset[bcm_ind], 0.0), 2.0); + // Calculate the charge for this scaler read + fBCM_delta_charge[bcm_ind] = fDeltaTime * cur_temp; + // Assign the charge to dvars + dvars[ivar] = fBCM_delta_charge[bcm_ind]; + } + } + } + } + + // If user has set fUseFirstEvent=kFALSE (then use dvarsFirst to store the information for + // the 1st event, and leave dvars at 0.0) (The same calculations as above, but assign + // dvars=0.0, so that it does not count when written to the scaler tree) + else { // ifnotusefirstevent + + if (scalerloc[ivar]->ikind == ICOUNT) { + dvarsFirst[ivar] = fScalerChan[ichan]; + dvars[ivar] = 0.0; + } + + if (scalerloc[ivar]->ikind == ITIME) { + dvarsFirst[ivar] = fDeltaTime; + dvars[ivar] = 0.0; + } + + if (scalerloc[ivar]->ikind == IRATE) { + dvarsFirst[ivar] = (fScalerChan[ichan]) / fDeltaTime; + dvars[ivar] = 0.0; + } + + if (scalerloc[ivar]->ikind == ICURRENT || scalerloc[ivar]->ikind == ICHARGE) { + Int_t bcm_ind = -1; + for (Int_t itemp = 0; itemp < fNumBCMs; itemp++) { + size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp])); + if (match != string::npos) { + bcm_ind = itemp; + } + } + + if (scalerloc[ivar]->ikind == ICURRENT) { + + dvarsFirst[ivar] = 0.0; + dvars[ivar] = 0.0; + + if (bcm_ind != -1) { + Double_t cur_temp = + ((fScalerChan[ichan]) / fDeltaTime - fBCM_Offset[bcm_ind]) / fBCM_Gain[bcm_ind]; + cur_temp = + cur_temp + fBCM_SatQuadratic[bcm_ind] * + TMath::Power(TMath::Max(cur_temp - fBCM_SatOffset[i], 0.0), 2.0); + dvarsFirst[ivar] = cur_temp; + } + + if (bcm_ind == fbcm_Current_Threshold_Index) + scal_current = dvarsFirst[ivar]; + } + + if (scalerloc[ivar]->ikind == ICHARGE) { + + if (bcm_ind != -1) { + Double_t cur_temp = + ((fScalerChan[ichan]) / fDeltaTime - fBCM_Offset[bcm_ind]) / fBCM_Gain[bcm_ind]; + cur_temp = + cur_temp + + fBCM_SatQuadratic[bcm_ind] * + TMath::Power(TMath::Max(cur_temp - fBCM_SatOffset[bcm_ind], 0.0), 2.0); + fBCM_delta_charge[bcm_ind] = fDeltaTime * cur_temp; + dvarsFirst[ivar] = fBCM_delta_charge[bcm_ind]; + } + } + } + } + } else { + _param_logger->warn("{}: ERROR: incorrect index {} {} {}", here, ivar, idx, ichan); + } + } + + // Calculate Scaler Quantities for ALL OTHER SCALER READS (OTHER THAN THE FIRST READ) + else { // evcount != 0 + + if ((ivar < scalerloc.size()) && (idx < scalers.size()) && (ichan < MAXCHAN)) { + + if (scalerloc[ivar]->ikind == ICOUNT) { + dvars[ivar] = fScalerChan[ichan]; + } + + if (scalerloc[ivar]->ikind == ITIME) { + dvars[ivar] = fDeltaTime; + } + + if (scalerloc[ivar]->ikind == IRATE) { + dvars[ivar] = fScalerChan[ichan] / fDeltaTime; + } + + if (scalerloc[ivar]->ikind == ICURRENT || scalerloc[ivar]->ikind == ICHARGE) { + Int_t bcm_ind = -1; + for (Int_t itemp = 0; itemp < fNumBCMs; itemp++) { + size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp])); + if (match != string::npos) { + bcm_ind = itemp; + } + } + if (scalerloc[ivar]->ikind == ICURRENT) { + dvars[ivar] = 0.; + + if (bcm_ind != -1) { + + if (fDeltaTime > 0) { + Double_t cur_temp = + (fScalerChan[ichan] / fDeltaTime - fBCM_Offset[bcm_ind]) / fBCM_Gain[bcm_ind]; + cur_temp = + cur_temp + + fBCM_SatQuadratic[bcm_ind] * + TMath::Power(TMath::Max(cur_temp - fBCM_SatOffset[bcm_ind], 0.0), 2.0); + dvars[ivar] = cur_temp; + } + } + if (bcm_ind == fbcm_Current_Threshold_Index) + scal_current = dvars[ivar]; + } + + if (scalerloc[ivar]->ikind == ICHARGE) { + + if (bcm_ind != -1) { + dvars[ivar] = 0.0; + + if (fDeltaTime > 0) { + Double_t cur_temp = + (fScalerChan[ichan] / fDeltaTime - fBCM_Offset[bcm_ind]) / fBCM_Gain[bcm_ind]; + cur_temp = + cur_temp + + fBCM_SatQuadratic[bcm_ind] * + TMath::Power(TMath::Max(cur_temp - fBCM_SatOffset[bcm_ind], 0.0), 2.0); + fBCM_delta_charge[bcm_ind] = fDeltaTime * cur_temp; + } + dvars[ivar] = fBCM_delta_charge[bcm_ind]; + } + } + } + + } else { + _param_logger->warn("{}: ERROR: incorrect index {} {} {}", here, ivar, idx, ichan); + } + } + } + + // Analyze Scaler Reads ONLY FOR SCAL_CURRENTS > BCM_CURRENT THRESHOLD + //(These variables have the name structure: varibaleName_Cut) + + for (size_t i = 0; i < scalerloc.size(); i++) { + size_t ivar = scalerloc[i]->ivar; + size_t ichan = scalerloc[i]->ichan; + + if (scalerloc[ivar]->ikind == ICUT + ICOUNT) { + if (scal_current > fbcm_Current_Threshold) { + dvars[ivar] = fScalerChan[ichan]; + } + } + + if (scalerloc[ivar]->ikind == ICUT + ICHARGE) { + Int_t bcm_ind = -1; + for (Int_t itemp = 0; itemp < fNumBCMs; itemp++) { + size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp])); + if (match != string::npos) { + bcm_ind = itemp; + } + } + if (scal_current > fbcm_Current_Threshold && bcm_ind != -1) { + dvars[ivar] = fBCM_delta_charge[bcm_ind]; + } + } + + if (scalerloc[ivar]->ikind == ICUT + ITIME) { + if (scal_current > fbcm_Current_Threshold) { + dvars[ivar] = fDeltaTime; + } + } + } + + //-------------------------------------- + + // C.Y. 12/13/2020 : Calculate the asymmetries / errors at the end of each quartet (S.A. Wood + // approach) + + if (actualhelicity != 0) { + + // Reset fHaveCycle to kFALSE at the start of each quartet (e.g. - + + -, + - - + + if (quartetphase == 0) { + fHaveCycle[0] = fHaveCycle[1] = fHaveCycle[2] = fHaveCycle[3] = kFALSE; + } + + // Check if BCM scaler current is above set threshold + if (scal_current > fbcm_Current_Threshold && + (quartetphase == 0 || fHaveCycle[max(quartetphase - 1, 0)])) { + fHaveCycle[quartetphase] = kTRUE; + + // Loop over each BCM to get the charge for each cycle of a quartet + for (Int_t i = 0; i < fNumBCMs; i++) { + fChargeCycle[quartetphase][i] = fBCM_delta_charge[i]; + } + + // Loop over each Scaler Channel to the the counts for each cycle of a quartet + for (Int_t i = 0; i < fNScalerChannels; i++) { + fScalCycle[quartetphase][i] = fScalerChan[i]; + } + + // Set the time for each cycle of the quartet + fTimeCycle[quartetphase] = fDeltaTime; + } + + // Compute asymmetries at the end of each quartet + if (quartetphase == 3 && fHaveCycle[3]) { + + // Loop over BCMs + for (Int_t i = 0; i < fNumBCMs; i++) { + + // compute charge asymmetry for each quartet at the end of said quartet + Double_t asy = + actualhelicity * + (fChargeCycle[0][i] + fChargeCycle[3][i] - fChargeCycle[1][i] - fChargeCycle[2][i]) / + (fChargeCycle[0][i] + fChargeCycle[3][i] + fChargeCycle[1][i] + fChargeCycle[2][i]); + + fChargeSum[i] += + fChargeCycle[0][i] + fChargeCycle[1][i] + fChargeCycle[2][i] + fChargeCycle[3][i]; + + // keep track of sums for proper error calculation + fChargeAsymSum[i] += asy; + fChargeAsymSum2[i] += asy * asy; + } + + //------- + + // Loop over Scaler Channels + for (Int_t i = 0; i < fNScalerChannels; i++) { + + // compute scaler asymmetry for each quartet at the end of said quartet + Double_t asy = actualhelicity * + (fScalCycle[0][i] + fScalCycle[3][i] - fScalCycle[1][i] - fScalCycle[2][i]) / + (fScalCycle[0][i] + fScalCycle[3][i] + fScalCycle[1][i] + fScalCycle[2][i]); + + fScalSum[i] += fScalCycle[0][i] + fScalCycle[1][i] + fScalCycle[2][i] + fScalCycle[3][i]; + + // keep track of sums for proper error calculation + fScalAsymSum[i] += asy; + fScalAsymSum2[i] += asy * asy; + } + + //------- + + // compute time asymmetry for each quartet at the end of said quartet + Double_t asy = actualhelicity * + (fTimeCycle[0] + fTimeCycle[3] - fTimeCycle[1] - fTimeCycle[2]) / + (fTimeCycle[0] + fTimeCycle[3] + fTimeCycle[1] + fTimeCycle[2]); + + // keep track of total time + fTimeSum += fTimeCycle[0] + fTimeCycle[1] + fTimeCycle[2] + fTimeCycle[3]; + + // keep track of sums for proper error calculation + fTimeAsymSum += asy; + fTimeAsymSum2 += asy * asy; + + //------ + + // keep track of the total number of quartets + fQuartetCount++; + } + } + + //-------------------------------------- + + // increment scaler reads + evcount = evcount + 1; + evcountR = evcount; + + // clear Genscaler scalers + for (size_t j = 0; j < scalers.size(); j++) + scalers[j]->Clear(""); + + // C.Y. 12/02/2020 Fill Scaler Tree Here + if (fScalerTree) { + fScalerTree->Fill(); + } + return (0); } //_____________________________________________________________________________ Int_t THcHelicityScaler::RanBit30(Int_t ranseed) { - UInt_t bit7 = (ranseed & 0x00000040) != 0; UInt_t bit28 = (ranseed & 0x08000000) != 0; UInt_t bit29 = (ranseed & 0x10000000) != 0; @@ -451,9 +1034,13 @@ Int_t THcHelicityScaler::RanBit30(Int_t ranseed) { //_____________________________________________________________________________ THaAnalysisObject::EStatus THcHelicityScaler::Init(const TDatime& date) { + const static char* const here = "THcHelicityScaler::Init"; ReadDatabase(date); + const int LEN = 200; + char cbuf[LEN]; - fStatus = kOK; + fStatus = kOK; + fNormIdx = -1; for (vector<UInt_t*>::iterator it = fDelayedEvents.begin(); it != fDelayedEvents.end(); ++it) delete[] * it; @@ -469,6 +1056,166 @@ THaAnalysisObject::EStatus THcHelicityScaler::Init(const TDatime& date) { fROC = 8; // Default to SHMS crate } + // C.Y. 11/26/2020 : Read In and Parse the variables in the helicity scaler map file + TString dfile; + dfile = fName + "scaler.txt"; + + TString sname0 = "Scalevt"; + TString sname; + sname = "hel" + fName + sname0; // This should be: 'helPScalevt' or 'helHScalevt' + + // Open helicity scaler .dat map file + FILE* fi = OpenFile(sname.Data(), date); + if (!fi) { + _param_logger->warn("{}: Cannot find db file for {} scaler event handler", here, fName); + return kFileError; + } + + size_t minus1 = -1; + size_t pos1; + string scomment = "#"; + string svariable = "variable"; + string smap = "map"; + vector<string> dbline; + + while (fgets(cbuf, LEN, fi) != NULL) { + std::string sin(cbuf); + std::string sinput(sin.substr(0, sin.find_first_of("#"))); + if (fDebugFile) + *fDebugFile << "string input " << sinput << endl; + dbline = vsplit(sinput); + if (dbline.size() > 0) { + pos1 = FindNoCase(dbline[0], scomment); + if (pos1 != minus1) + continue; + pos1 = FindNoCase(dbline[0], svariable); + + if (pos1 != minus1 && dbline.size() > 4) { + string sdesc = ""; + for (size_t j = 5; j < dbline.size(); j++) + sdesc = sdesc + " " + dbline[j]; + UInt_t islot = atoi(dbline[1].c_str()); + UInt_t ichan = atoi(dbline[2].c_str()); + UInt_t ikind = atoi(dbline[3].c_str()); + if (fDebugFile) + *fDebugFile << "add var " << dbline[1] << " desc = " << sdesc << " islot= " << islot + << " " << ichan << " " << ikind << endl; + TString tsname(dbline[4].c_str()); + TString tsdesc(sdesc.c_str()); + AddVars(tsname, tsdesc, islot, ichan, ikind); + // add extra scaler which is cut on the current + if (ikind == ICOUNT || ikind == ITIME || ikind == ICHARGE) { + tsname = tsname + "Cut"; + AddVars(tsname, tsdesc, islot, ichan, ICUT + ikind); + } + } + + pos1 = FindNoCase(dbline[0], smap); + if (fDebugFile) + *fDebugFile << "map ? " << dbline[0] << " " << smap << " " << pos1 << " " + << dbline.size() << endl; + if (pos1 != minus1 && dbline.size() > 6) { + Int_t imodel, icrate, islot, inorm; + UInt_t header, mask; + char cdum[20]; + sscanf(sinput.c_str(), "%s %d %d %d %x %x %d \n", cdum, &imodel, &icrate, &islot, &header, + &mask, &inorm); + if ((fNormSlot >= 0) && (fNormSlot != inorm)) + _param_logger->warn("{}: contradictory norm slot {} {}", here, fNormSlot, inorm); + fNormSlot = + inorm; // slot number used for normalization. This variable is not used but is checked. + Int_t clkchan = -1; + Double_t clkfreq = 1; + if (dbline.size() > 8) { + clkchan = atoi(dbline[7].c_str()); + clkfreq = 1.0 * atoi(dbline[8].c_str()); + fClockChan = clkchan; + fClockFreq = clkfreq; + } + if (fDebugFile) { + *fDebugFile << "map line " << dec << imodel << " " << icrate << " " << islot << endl; + *fDebugFile << " header 0x" << hex << header << " 0x" << mask << dec << " " << inorm + << " " << clkchan << " " << clkfreq << endl; + } + + switch (imodel) { + case 3801: // Hall C Helicity Scalers (SIS 3801) + scalers.push_back(new Scaler3801(icrate, islot)); + if (!fOnlyBanks) + fRocSet.insert(icrate); + fModuleSet.insert(imodel); + break; + } + + if (scalers.size() > 0) { + UInt_t idx = scalers.size() - 1; + // Headers must be unique over whole event, not + // just within a ROC + scalers[idx]->SetHeader(header, mask); + // The normalization slot has the clock in it, so we automatically recognize it. + // fNormIdx is the index in scaler[] and + // fNormSlot is the slot#, checked for consistency + if (clkchan >= 0) { + scalers[idx]->SetClock(defaultDT, clkchan, clkfreq); + _param_logger->info("{}: Setting scaler clock ... channel = {} ... freq = {}", here, + clkchan, clkfreq); + if (fDebugFile) + *fDebugFile << "Setting scaler clock ... channel = " << clkchan + << " ... freq = " << clkfreq << endl; + fNormIdx = idx; + if (islot != fNormSlot) + _param_logger->warn("{}: contradictory norm slot {}", here, islot); + } + } + } + } + + } // end while loop + + // can't compare UInt_t to Int_t (compiler warning), so do this + nscalers = 0; + for (size_t i = 0; i < scalers.size(); i++) + nscalers++; + // need to do LoadNormScaler after scalers created and if fNormIdx found + if (fDebugFile) + *fDebugFile << "fNormIdx = " << fNormIdx << endl; + if ((fNormIdx >= 0) && fNormIdx < nscalers) { + for (Int_t i = 0; i < nscalers; i++) { + if (i == fNormIdx) + continue; + scalers[i]->LoadNormScaler(scalers[fNormIdx]); + } + } + + // Called after AddVars() has been called + DefVars(); + + // Verify that the slots are not defined twice + for (UInt_t i1 = 0; i1 < scalers.size() - 1; i1++) { + for (UInt_t i2 = i1 + 1; i2 < scalers.size(); i2++) { + if (scalers[i1]->GetSlot() == scalers[i2]->GetSlot()) + _param_logger->warn("{}: same slot defined twice", here); + } + } + // Identify indices of scalers[] vector to variables. + for (UInt_t i = 0; i < scalers.size(); i++) { + for (UInt_t j = 0; j < scalerloc.size(); j++) { + if (scalerloc[j]->islot == static_cast<UInt_t>(scalers[i]->GetSlot())) + scalerloc[j]->index = i; + } + } + + if (fDebugFile) + *fDebugFile << "THcHelicityScaler:: Name of scaler bank " << fName << endl; + for (size_t i = 0; i < scalers.size(); i++) { + if (fDebugFile) { + *fDebugFile << "Scaler # " << i << endl; + scalers[i]->SetDebugFile(fDebugFile); + scalers[i]->DebugPrint(fDebugFile); + } + } + + //------Initialize Helicity Variables / Arrays----- fNTriggers = 0; fNTrigsInBuf = 0; fFirstCycle = -100; @@ -476,97 +1223,212 @@ THaAnalysisObject::EStatus THcHelicityScaler::Init(const TDatime& date) { fRingSeed_actual = 0; fNBits = 0; fNTriggersPlus = fNTriggersMinus = 0; - fHScalers[0].resize(fNScalerChannels); - fHScalers[1].resize(fNScalerChannels); - fScalerSums.resize(fNScalerChannels); - fAsymmetry.resize(fNScalerChannels); - fAsymmetryError.resize(fNScalerChannels); + fHScalers[0].resize(fNScalerChannels); //+ helicity scaler counts + fHScalers[1].resize(fNScalerChannels); //- helicity scaler counts + fScalerSums.resize(fNScalerChannels); // total helicity scaler counts (hel=0, excluded) + fScalerChan.resize(fNScalerChannels); // C.Y. 11/26/2020 : added array to store helicity + // information per channel + for (Int_t i = 0; i < fNScalerChannels; i++) { - fHScalers[0][i] = 0.0; - fHScalers[1][i] = 0.0; - fScalerSums[0] = 0.0; - fAsymmetry[0] = 0.0; - fAsymmetryError[0] = 0.0; + fHScalers[0][i] = 0.0; + fHScalers[1][i] = 0.0; + fScalerSums[i] = 0.0; + fScalerChan[i] = 0.0; + } + + fTimePlus = fTimeMinus = 0.0; + fTriggerAsymmetry = 0.0; + + //------C.Y.: 12/13/2020 Initialize Variables for quartet-by-quartet asymmetries (include BCM + // current threshold cut)--------- (and error calculation) + + for (Int_t i = 0; i < 4; i++) { + + fChargeCycle[i].resize(fNumBCMs); + fScalCycle[i].resize(fNScalerChannels); + + fHaveCycle[i] = kFALSE; + + for (Int_t j = 0; j < fNumBCMs; j++) { + fChargeCycle[i][j] = 0.0; + } + + for (Int_t j = 0; j < fNScalerChannels; j++) { + fScalCycle[i][j] = 0.0; + } + + fTimeCycle[i] = 0.0; } - fCharge.resize(fNumBCMs); + // Initialize quartet counter + fQuartetCount = 0.0; + + // Initialize variables for time asymmetry calculation + fTimeSum = 0.0; + fTimeAsymmetry = 0.0; + fTimeAsymmetryError = 0.0; + fTimeAsymSum = 0.0; + fTimeAsymSum2 = 0.0; + + // Initialize variables for charge asymmetry calculation + fChargeSum.resize(fNumBCMs); fChargeAsymmetry.resize(fNumBCMs); + fChargeAsymmetryError.resize(fNumBCMs); + fChargeAsymSum.resize(fNumBCMs); + fChargeAsymSum2.resize(fNumBCMs); - fTime = fTimeAsymmetry = 0; - fTriggerAsymmetry = 0.0; + for (Int_t i = 0; i < fNumBCMs; i++) { + fChargeSum[i] = 0.0; + fChargeAsymmetry[i] = 0.0; + fChargeAsymSum[i] = 0.0; + fChargeAsymSum2[i] = 0.0; + } + // Initialize variables for scaler asymmetry calculation + fScalSum.resize(fNScalerChannels); + fScalAsymmetry.resize(fNScalerChannels); + fScalAsymmetryError.resize(fNScalerChannels); + fScalAsymSum.resize(fNScalerChannels); + fScalAsymSum2.resize(fNScalerChannels); + + for (Int_t i = 0; i < fNScalerChannels; i++) { + fScalSum[i] = 0.0; + fScalAsymmetry[i] = 0.0; + fScalAsymSum[i] = 0.0; + fScalAsymSum2[i] = 0.0; + } + + //------------------------------------------------------------------------------------------ + + // Call MakeParms() to define variables to be used in report file MakeParms(); return kOK; } void THcHelicityScaler::MakeParms() { - /** - Put Various helicity scaler results in gHcParms so they can be included in results. - */ + + // Put Various helicity scaler results in gHcParms so they can be included in results. + + // no bcm cut required gHcParms->Define(Form("g%s_hscaler_plus[%d]", fName.Data(), fNScalerChannels), - "Plus Helcity Scalers", fHScalers[0][0]); + "Plus Helcity Scalers", *(fHScalers[0])); + gHcParms->Define(Form("g%s_hscaler_minus[%d]", fName.Data(), fNScalerChannels), - "Minus Helcity Scalers", fHScalers[1][0]); - gHcParms->Define(Form("g%s_hscaler_sum[%d]", fName.Data(), fNScalerChannels), - "Helcity Scalers Sum", fScalerSums[0]); - gHcParms->Define(Form("g%s_hscaler_asy[%d]", fName.Data(), fNScalerChannels), - "Helicity Scaler Asymmetry[%d]", fAsymmetry[0]); - gHcParms->Define(Form("g%s_hscaler_asyerr[%d]", fName.Data(), fNScalerChannels), - "Helicity Scaler Asymmetry Error[%d]", fAsymmetryError[0]); + "Minus Helcity Scalers", *(fHScalers[1])); + + // gHcParms->Define(Form("g%s_hscaler_sum[%d]",fName.Data(),fNScalerChannels), + // "Helcity Scalers Sum",*fScalerSums); + gHcParms->Define(Form("g%s_hscaler_triggers", fName.Data()), "Total Helicity Scaler Triggers", fNTriggers); + gHcParms->Define(Form("g%s_hscaler_triggers_plus", fName.Data()), "Positive Helicity Scaler Triggers", fNTriggersPlus); + gHcParms->Define(Form("g%s_hscaler_triggers_minus", fName.Data()), "Negative Helicity Scaler Triggers", fNTriggersMinus); + + gHcParms->Define(Form("g%s_hscaler_trigger_asy", fName.Data()), "Helicity Trigger Asymmetry", + fTriggerAsymmetry); + + // gHcParms->Define(Form("g%s_hscaler_time_plus",fName.Data()), + // "Positive Helicity Time",fTimePlus); + + // gHcParms->Define(Form("g%s_hscaler_time_minus",fName.Data()), + // "Negative Helicity Time",fTimeMinus); + + // bcm cut + gHcParms->Define(Form("g%s_hscaler_sum[%d]", fName.Data(), fNScalerChannels), + "Helcity Scalers Sum", *fScalSum); + + gHcParms->Define(Form("g%s_hscaler_asy[%d]", fName.Data(), fNScalerChannels), + "Helicity Scaler Asymmetry[%d]", *fScalAsymmetry); + + gHcParms->Define(Form("g%s_hscaler_asyerr[%d]", fName.Data(), fNScalerChannels), + "Helicity Scaler Asymmetry Error[%d]", *fScalAsymmetryError); + gHcParms->Define(Form("g%s_hscaler_charge[%d]", fName.Data(), fNumBCMs), "Helicity Gated Charge", - fCharge[0]); + *fChargeSum); + gHcParms->Define(Form("g%s_hscaler_charge_asy[%d]", fName.Data(), fNumBCMs), - "Helicity Gated Charge Asymmetry", fChargeAsymmetry[0]); - gHcParms->Define(Form("g%s_hscaler_time", fName.Data()), "Helicity Gated Time (sec)", fTime); + "Helicity Gated Charge Asymmetry", *fChargeAsymmetry); + + gHcParms->Define(Form("g%s_hscaler_charge_asyerr[%d]", fName.Data(), fNumBCMs), + "Helicity Gated Charge Asymmetry Error", *fChargeAsymmetryError); + + gHcParms->Define(Form("g%s_hscaler_time", fName.Data()), "Helicity Gated Time (sec)", fTimeSum); + gHcParms->Define(Form("g%s_hscaler_time_asy", fName.Data()), "Helicity Gated Time Asymmetry", fTimeAsymmetry); - gHcParms->Define(Form("g%s_hscaler_trigger_asy", fName.Data()), "Helicity Trigger Asymmetry", - fTriggerAsymmetry); + + gHcParms->Define(Form("g%s_hscaler_time_asyerr", fName.Data()), + "Helicity Gated Time Asymmetry Error", fTimeAsymmetryError); } -Double_t THcHelicityScaler::GetPlusCharge(const std::string& name) { - size_t i = 0; - for (; i < fNumBCMs; ++i) { - if (name == fBCM_Name[i]) { - break; - } - } - auto it = bcmindex.find(name); +//--------------------C.Y. Sep 20, 2020 : Added Utility Functions-------------------- + +void THcHelicityScaler::AddVars(TString name, TString desc, UInt_t islot, UInt_t ichan, + UInt_t ikind) { + if (fDebugFile) + *fDebugFile << "C.Y. | Calling THcHelicityScaler::AddVars() " << endl; + // need to add fName here to make it a unique variable. (Left vs Right HRS, for example) + TString name1 = fName + name; + TString desc1 = fName + desc; + // We don't yet know the correspondence between index of scalers[] and slots. + // Will put that in later. + scalerloc.push_back(new HCScalerLoc(name1, desc1, 0, islot, ichan, ikind, scalerloc.size())); +} - if (it != bcmindex.end() && i < fNumBCMs) { - auto index = it->second; - Double_t clock = fHScalers[0][clockindex]; - Double_t counts = fHScalers[0][index]; - return (counts - (clock / clockfreq) * fBCM_Offset[i]) / fBCM_Gain[i]; +void THcHelicityScaler::DefVars() { + const char* const here = "THcHelicityScaler::DefVars()"; + if (fDebugFile) + *fDebugFile << "C.Y. | Calling THcHelicityScaler::DefVars() " << endl; + // called after AddVars has finished being called. + Nvars = scalerloc.size(); + if (Nvars == 0) + return; + dvars.resize(Nvars); // dvars is a member of this class + dvarsFirst.resize(Nvars); // dvarsFirst is a member of this class + dvars = {0.}; + dvarsFirst = {0.}; + if (gHaVars) { + if (fDebugFile) + *fDebugFile << "THcScalerEVtHandler:: Have gHaVars " << gHaVars << endl; + } else { + _param_logger->warn("{}: No gHaVars ?! Well, that's a problem !!", here); + return; + } + if (fDebugFile) + *fDebugFile << "THcHelicityScaler:: scalerloc size " << scalerloc.size() << endl; + const Int_t* count = 0; + for (size_t i = 0; i < scalerloc.size(); i++) { + gHaVars->DefineByType(scalerloc[i]->name.Data(), scalerloc[i]->description.Data(), &dvars[i], + kDouble, count); } - _param_logger->warn("THcHelicityScaler::GetPlusCharge: Cannot find scaler {}, return 0.", name); - return 0.; } -Double_t THcHelicityScaler::GetMinusCharge(const std::string& name) { - size_t i = 0; - for (; i < fNumBCMs; ++i) { - if (name == fBCM_Name[i]) { - break; - } +size_t THcHelicityScaler::FindNoCase(const string& sdata, const string& skey) { + // Find iterator of word "sdata" where "skey" starts. Case insensitive. + string sdatalc, skeylc; + sdatalc = ""; + skeylc = ""; + for (string::const_iterator p = sdata.begin(); p != sdata.end(); ++p) { + sdatalc += tolower(*p); } - auto it = bcmindex.find(name); - - if (it != bcmindex.end() && i < fNumBCMs) { - auto index = it->second; - Double_t clock = fHScalers[1][clockindex]; - Double_t counts = fHScalers[1][index]; - return (counts - (clock / clockfreq) * fBCM_Offset[i]) / fBCM_Gain[i]; + for (string::const_iterator p = skey.begin(); p != skey.end(); ++p) { + skeylc += tolower(*p); } - _param_logger->warn("THcHelicityScaler::GetMinusCharge: Cannot find scaler {}, return 0.", name); - return 0.; + if (sdatalc.find(skeylc, 0) == string::npos) + return -1; + return sdatalc.find(skeylc, 0); +}; + +void WriteJson(const std::string& path) { + std::ofstream ofile{fmt::format("{}/hel_scalers_{}.json", path, j_helicity["run_number"]}; + ofile << std::setw(4) << j_helicity << "\n"; } +//--------------------------------------------------------------------------------- + ClassImp(THcHelicityScaler) diff --git a/src/THcHelicityScaler.h b/src/THcHelicityScaler.h index 650eb4bb200a9fdb6c8422998264174395043d51..461c2ce5fa2b4f34bd3e37b2d36047c23f3c9128 100644 --- a/src/THcHelicityScaler.h +++ b/src/THcHelicityScaler.h @@ -11,6 +11,7 @@ #include "Decoder.h" #include "THaEvtTypeHandler.h" #include "THaRunBase.h" +#include "THcScalerEvtHandler.h" #include "TString.h" #include "TTree.h" #include "hcana/Logger.h" @@ -21,6 +22,7 @@ #include <vector> class THcHelicity; +class HCScalerLoc; class THcHelicityScaler : public hcana::ConfigLogging<THaEvtTypeHandler> { @@ -28,32 +30,43 @@ public: THcHelicityScaler(const char*, const char*); virtual ~THcHelicityScaler(); - Int_t Analyze(THaEvData* evdata); - Int_t AnalyzeBuffer(UInt_t* rdata); - Int_t AnalyzeHelicityScaler(UInt_t* p); + Int_t Analyze(THaEvData* evdata); + Int_t AnalyzeBuffer(UInt_t* rdata); + Int_t AnalyzeHelicityScaler(UInt_t* p); virtual EStatus Init(const TDatime& run_time); - virtual Int_t ReadDatabase(const TDatime& date); - virtual Int_t End(THaRunBase* r = 0); - - virtual void SetUseFirstEvent(Bool_t b = kFALSE) { fUseFirstEvent = b; } - virtual void SetDelayedType(int evtype); - virtual void SetROC(Int_t roc) { fROC = roc; } - virtual void SetBankID(Int_t bankid) { fBankID = bankid; } - virtual void SetNScalerChannels(Int_t n) { fNScalerChannels = n; } - virtual Int_t GetNevents() { return fNTrigsInBuf; } - virtual Int_t GetNcycles() { return fNTriggers; } - virtual Int_t GetEvNum() { return evNumber; } - virtual Int_t* GetHelicityHistoryP() { return fHelicityHistory; } - virtual Int_t GetReportedSeed() { return fRingSeed_reported; } - virtual Int_t GetReportedActual() { return fRingSeed_actual; } - virtual Bool_t IsSeedGood() { return fNBits >= 30; } + virtual Int_t ReadDatabase(const TDatime& date); + virtual Int_t End(THaRunBase* r = 0); + + virtual void SetUseFirstEvent(Bool_t b = kFALSE) { fUseFirstEvent = b; } + virtual void SetDelayedType(int evtype); + virtual void SetROC(Int_t roc) { fROC = roc; } + virtual void SetBankID(Int_t bankid) { fBankID = bankid; } + virtual void SetNScalerChannels(Int_t n) { fNScalerChannels = n; } + virtual Int_t GetNevents() { return fNTrigsInBuf; } + virtual Int_t GetNcycles() { return fNTriggers; } + virtual Int_t GetEvNum() { return evNumber; } + virtual Int_t* GetHelicityHistoryP() { return fHelicityHistory; } + virtual Int_t GetReportedSeed() { return fRingSeed_reported; } + virtual Int_t GetReportedActual() { return fRingSeed_actual; } + virtual Bool_t IsSeedGood() { return fNBits >= 30; } Double_t GetPlusCharge(const std::string& name); Double_t GetMinusCharge(const std::string& name); + // utility function to write out json helicity file + void WriteJson(const std::string& path); + private: + //------------C.Y. Sep 20, 2020 :: Added Utility Function Prototypes---------------- + void AddVars(TString name, TString desc, UInt_t iscal, UInt_t ichan, UInt_t ikind); + void DefVars(); + static size_t FindNoCase(const std::string& sdata, const std::string& skey); + + std::vector<Decoder::GenScaler*> scalers; + std::vector<HCScalerLoc*> scalerloc; + Int_t RanBit30(Int_t ranseed); - void MakeParms(); + void MakeParms(); UInt_t fBankID; // Helicity Scaler variables @@ -76,9 +89,44 @@ private: std::vector<Double_t> fScalerSums, fAsymmetry, fAsymmetryError; std::vector<Double_t> fCharge, fChargeAsymmetry; Double_t fTime; - Double_t fTimeAsymmetry; + Double_t fTimePlus; + Double_t fTimeMinus; Double_t fTriggerAsymmetry; + //---- C.Y.: 12/14/2020 Variables for quartet-by-quartet asymmetry/error calculations ---- + Bool_t fHaveCycle[4]; + + Int_t fQuartetCount; // keep track of number of quartets + + // quartet-by-quartet time asymmetry variables + Double_t fTimeCycle[4]; + Double_t fTimeSum; + Double_t fTimeAsymmetry; + Double_t fTimeAsymmetryError; + Double_t fTimeAsymSum; + Double_t fTimeAsymSum2; + + // quartet-by-quartet scaler counts asymmetry variables + std::vector<Double_t> fScalCycle[4]; + std::vector<Double_t> fScalSum; // reminder: need to initialize + std::vector<Double_t> fScalAsymmetry; + std::vector<Double_t> fScalAsymmetryError; + std::vector<Double_t> fScalAsymSum; + std::vector<Double_t> fScalAsymSum2; + + // quartet-by-quartet charge asymmetry variables + std::vector<Double_t> fChargeCycle[4]; + std::vector<Double_t> fChargeSum; + std::vector<Double_t> fChargeAsymmetry; + std::vector<Double_t> fChargeAsymmetryError; + std::vector<Double_t> fChargeAsymSum; + std::vector<Double_t> fChargeAsymSum2; + + //---------------------- + + //----C.Y. Nov 26, 2020---- + std::vector<Double_t> fScalerChan; + std::vector<UInt_t*> fDelayedEvents; Int_t fROC; Int_t fNScalerChannels; // Number of scaler channels/event @@ -86,12 +134,43 @@ private: Int_t fNumBCMs; std::vector<Double_t> fBCM_Gain, fBCM_Offset; std::vector<std::string> fBCM_Name; + //---C.Y. Sep 2020 : Added additional BCM-related variables-- + std::vector<Double_t> fBCM_SatOffset; + std::vector<Double_t> fBCM_SatQuadratic; + std::vector<Double_t> fBCM_delta_charge; + Double_t fTotalTime; + Double_t fDeltaTime; + Double_t fPrevTotalTime; + Double_t fbcm_Current_Threshold; + Double_t fClockFreq; + Int_t fbcm_Current_Threshold_Index; + + //----C.Y. Sep 20, 2020 : Added additional variables----- + // (required by utility functions and scaler tree output) + UInt_t evcount; + Double_t evcountR; + UInt_t evNumber; + Double_t evNumberR; + Double_t actualHelicityR; + Double_t quartetphaseR; + Int_t Nvars, ifound, fNormIdx, fNormSlot, nscalers; + std::vector<Double_t> dvars; + std::vector<Double_t> dvarsFirst; + TTree* fScalerTree; + Bool_t fOnlySyncEvents; + Bool_t fOnlyBanks; + Int_t fClockChan; + UInt_t fLastClock; + std::set<UInt_t> fRocSet; + std::set<UInt_t> fModuleSet; + //-------------------------------------------------------- + + // json file with helicity info + json j_helicity; THcHelicityScaler(const THcHelicityScaler& fh); THcHelicityScaler& operator=(const THcHelicityScaler& fh); - UInt_t evNumber; - ClassDef(THcHelicityScaler, 0) // Scaler Event handler }; diff --git a/src/THcParmList.cxx b/src/THcParmList.cxx index c2a3c88a47b772a290968e65952403f8c35b186f..deef2e9a9c31ef700685f43810d74ceaf78f40e3 100644 --- a/src/THcParmList.cxx +++ b/src/THcParmList.cxx @@ -43,50 +43,48 @@ An instance of THaTextvars is created to hold the string parameters. #include <iomanip> #include "TBufferJSON.h" -#include "nlohmann/json.hpp" #include "TObjArray.h" #include "TObjString.h" #include "TSystem.h" +#include "nlohmann/json.hpp" -#include "THcParmList.h" -#include "THaVar.h" #include "THaFormula.h" +#include "THaVar.h" +#include "THcParmList.h" #include "TMath.h" /* #incluce <algorithm> include <fstream> include <cstring> */ -#include <iostream> -#include <fstream> #include <cassert> #include <cstdlib> -#include <stdexcept> +#include <fstream> +#include <iostream> #include <memory> +#include <stdexcept> using namespace std; -Int_t fDebug = 1; // Keep this at one while we're working on the code +Int_t fDebug = 1; // Keep this at one while we're working on the code #if __cplusplus < 201103L -# define SMART_PTR auto_ptr +#define SMART_PTR auto_ptr #else -# define SMART_PTR unique_ptr +#define SMART_PTR unique_ptr #endif ClassImp(THcParmList) -/// Create empty numerical and string parameter lists -THcParmList::THcParmList() : hcana::ConfigLogging<THaVarList>() -{ + /// Create empty numerical and string parameter lists + THcParmList::THcParmList() + : hcana::ConfigLogging<THaVarList>() { TextList = new THaTextvars; } -inline static bool IsComment( const string& s, string::size_type pos ) -{ - return ( pos != string::npos && pos < s.length() && - (s[pos] == '#' || s[pos] == ';' || s.substr(pos,2) == "//") ); +inline static bool IsComment(const string& s, string::size_type pos) { + return (pos != string::npos && pos < s.length() && + (s[pos] == '#' || s[pos] == ';' || s.substr(pos, 2) == "//")); } -void THcParmList::Load( const char* fname, Int_t RunNumber ) -{ +void THcParmList::Load(const char* fname, Int_t RunNumber) { /** Most parameter files used in the ENGINE should work. @@ -127,138 +125,136 @@ The ENGINE CTP support parameter "blocks" which were marked with static const char* const whtspc = " \t"; - ifstream ifiles[100]; // Should use stack instead + ifstream ifiles[100]; // Should use stack instead - Int_t nfiles=0; + Int_t nfiles = 0; ifiles[nfiles].open(fname); - if(ifiles[nfiles].is_open()) { - //cout << "Opening parameter file: [" << nfiles << "] " << fname << endl; + if (ifiles[nfiles].is_open()) { + // cout << "Opening parameter file: [" << nfiles << "] " << fname << endl; nfiles++; } - if(!nfiles) { - static const char* const here = "THcParmList::LoadFromFile"; - //Error (here, "error opening parameter file %s",fname); - return; // Need a success argument returned + if (!nfiles) { + static const char* const here = "THcParmList::LoadFromFile"; + // Error (here, "error opening parameter file %s",fname); + return; // Need a success argument returned } string line; - char varname[100]; - Int_t InRunRange; - Int_t currentindex = 0; - Int_t linecount=0; // Count of non comment/blank lines + char varname[100]; + Int_t InRunRange; + Int_t currentindex = 0; + Int_t linecount = 0; // Count of non comment/blank lines varname[0] = '\0'; - if(RunNumber > 0) { - InRunRange = 0; // Wait until run number range matching RunNumber is found - //cout << "Reading Parameters for run " << RunNumber << endl; + if (RunNumber > 0) { + InRunRange = 0; // Wait until run number range matching RunNumber is found + // cout << "Reading Parameters for run " << RunNumber << endl; } else { - InRunRange = 1; // Interpret all lines + InRunRange = 1; // Interpret all lines } - while(nfiles) { + while (nfiles) { string current_comment(""); // EJB_Note: existing_comment is never used. // string existing_comment(""); string::size_type start, pos = 0; - if(!getline(ifiles[nfiles-1],line)) { - ifiles[nfiles-1].close(); + if (!getline(ifiles[nfiles - 1], line)) { + ifiles[nfiles - 1].close(); nfiles--; // cout << nfiles << ": " << "Closed" << endl; continue; } // Look for include statement - if(line.compare(0,strlen(INCLUDESTR),INCLUDESTR)==0) { - line.erase(0,strlen(INCLUDESTR)); + if (line.compare(0, strlen(INCLUDESTR), INCLUDESTR) == 0) { + line.erase(0, strlen(INCLUDESTR)); pos = line.find_first_not_of(whtspc); // Strip leading white space - if(pos != string::npos && pos > 0 && pos < line.length()) { - line.erase(0,pos); + if (pos != string::npos && pos > 0 && pos < line.length()) { + line.erase(0, pos); } - char quotechar=line[0]; - if(quotechar == '"' || quotechar == '\'') { - line.erase(0,1); - line.erase(line.find_first_of(quotechar)); + char quotechar = line[0]; + if (quotechar == '"' || quotechar == '\'') { + line.erase(0, 1); + line.erase(line.find_first_of(quotechar)); } else { - line.erase(line.find_first_of(whtspc)); + line.erase(line.find_first_of(whtspc)); } // cout << line << endl; ifiles[nfiles].open(line.c_str()); - if(ifiles[nfiles].is_open()) { + if (ifiles[nfiles].is_open()) { _logger->info("Opening parameter file: [{}] {} ", nfiles, line); - //cout << "Opening parameter file: [" << nfiles << "] " << line << endl; - nfiles++; + // cout << "Opening parameter file: [" << nfiles << "] " << line << endl; + nfiles++; } continue; } // Blank line or comment? - if( line.empty() - || (start = line.find_first_not_of( whtspc )) == string::npos - || IsComment(line, start) ) + if (line.empty() || (start = line.find_first_not_of(whtspc)) == string::npos || + IsComment(line, start)) continue; // Get rid of trailing comments and leading and trailing whitespace // Need to save the comment and put it in the thVar - while( (pos = line.find_first_of("#;/", pos+1)) != string::npos ) { - if( IsComment(line, pos) ) { - current_comment.assign(line,pos+1,line.length()); - line.erase(pos); // Strip off comment - // Strip leading white space from comment - //cout << "CommentA: " << current_comment << endl; - pos = current_comment.find_first_not_of(whtspc); - if(pos!=string::npos && pos > 0 && pos < current_comment.length()) { - current_comment.erase(0,pos); - } - //cout << "CommentB: " << current_comment << endl; - break; + while ((pos = line.find_first_of("#;/", pos + 1)) != string::npos) { + if (IsComment(line, pos)) { + current_comment.assign(line, pos + 1, line.length()); + line.erase(pos); // Strip off comment + // Strip leading white space from comment + // cout << "CommentA: " << current_comment << endl; + pos = current_comment.find_first_not_of(whtspc); + if (pos != string::npos && pos > 0 && pos < current_comment.length()) { + current_comment.erase(0, pos); + } + // cout << "CommentB: " << current_comment << endl; + break; } } - pos = line.find_last_not_of( whtspc ); - assert( pos != string::npos ); - if( pos != string::npos && ++pos < line.length() ) + pos = line.find_last_not_of(whtspc); + assert(pos != string::npos); + if (pos != string::npos && ++pos < line.length()) line.erase(pos); pos = line.find_first_not_of(whtspc); // Strip leading white space - if(pos != string::npos && pos > 0 && pos < line.length()) { - line.erase(0,pos); + if (pos != string::npos && pos > 0 && pos < line.length()) { + line.erase(0, pos); } // Ignore begin and end statements - if(line.compare(0,5,"begin")==0 || - line.compare(0,3,"end")==0) { + if (line.compare(0, 5, "begin") == 0 || line.compare(0, 3, "end") == 0) { cout << "Skipping: " << line << endl; continue; } // Get rid of all white space not in quotes // Step through one char at a time - pos = 0; - int inquote=0; - char quotechar=' '; + pos = 0; + int inquote = 0; + char quotechar = ' '; // cout << "Unstripped line: |" << line << "|" << endl; - while(pos<line.length()) { - if(inquote) { - if(line[pos++] == quotechar) { // Possibly end of quoted string - if(line[pos] == quotechar) { // Protected quote - pos++; // Skip the protected quote - } else { // End of quoted string - inquote = 0; - quotechar = ' '; - pos++; - } - } + while (pos < line.length()) { + if (inquote) { + if (line[pos++] == quotechar) { // Possibly end of quoted string + if (line[pos] == quotechar) { // Protected quote + pos++; // Skip the protected quote + } else { // End of quoted string + inquote = 0; + quotechar = ' '; + pos++; + } + } } else { - if(line[pos] == ' ' || line[pos] == '\t') { - line.erase(pos,1); - } else if(line[pos] == '"' || line[pos] == '\'') { - quotechar = line[pos++];\ - inquote = 1; - } else { - pos++; - } + if (line[pos] == ' ' || line[pos] == '\t') { + line.erase(pos, 1); + } else if (line[pos] == '"' || line[pos] == '\'') { + quotechar = line[pos++]; + inquote = 1; + } else { + pos++; + } } } // cout << "Stripped line: |" << line << "|" << endl; @@ -269,96 +265,97 @@ The ENGINE CTP support parameter "blocks" which were marked with linecount++; // If RunNumber>0 and first line we encounter is not a run range, need to // print an error - if(RunNumber>0 && nfiles==1) { - if(line.find_first_not_of("0123456789-,")==string::npos) { // Interpret as runnum range - // Interpret line as a list of comma separated run numbers or ranges - TString runnums(line.c_str()); - SMART_PTR<TObjArray> runnumarr( runnums.Tokenize(",") ); - Int_t nranges=runnumarr->GetLast()+1; - - InRunRange = 0; - Int_t ind; - for(Int_t i=0;i<nranges;i++) { - TString runstr = ((TObjString *)runnumarr->At(i))->GetString(); - if(runstr.IsDec()) { // A single run number - if(RunNumber == runstr.Atoi()) { - InRunRange = 1; - break; - } - } else if ((ind=runstr.First('-'))>=0) { // A run range - TString start=runstr(0,ind); - TString end=runstr(ind+1,runstr.Length()); - if(start.IsDec() && end.IsDec()) { - if((RunNumber >= start.Atoi()) && (RunNumber <= end.Atoi())) { - InRunRange = 1; - break; - } - } - } - } - continue; // Skip to next line + if (RunNumber > 0 && nfiles == 1) { + if (line.find_first_not_of("0123456789-,") == string::npos) { // Interpret as runnum range + // Interpret line as a list of comma separated run numbers or ranges + TString runnums(line.c_str()); + SMART_PTR<TObjArray> runnumarr(runnums.Tokenize(",")); + Int_t nranges = runnumarr->GetLast() + 1; + + InRunRange = 0; + Int_t ind; + for (Int_t i = 0; i < nranges; i++) { + TString runstr = ((TObjString*)runnumarr->At(i))->GetString(); + if (runstr.IsDec()) { // A single run number + if (RunNumber == runstr.Atoi()) { + InRunRange = 1; + break; + } + } else if ((ind = runstr.First('-')) >= 0) { // A run range + TString start = runstr(0, ind); + TString end = runstr(ind + 1, runstr.Length()); + if (start.IsDec() && end.IsDec()) { + if ((RunNumber >= start.Atoi()) && (RunNumber <= end.Atoi())) { + InRunRange = 1; + break; + } + } + } + } + continue; // Skip to next line } else { - if(linecount==1) { - _logger->warn("THcParmList::Load in database mode but first line is not\n" - " a run number or run number range. Parameter definitions\n" - " will be ignored until a run number or range is specified.\n"); - } + if (linecount == 1) { + _logger->warn("THcParmList::Load in database mode but first line is not\n" + " a run number or run number range. Parameter definitions\n" + " will be ignored until a run number or range is specified.\n"); + } } } - if(!InRunRange) continue; + if (!InRunRange) + continue; // Interpret left of = as var name - Int_t valuestartpos=0; // Stays zero if no = found - Int_t ttype = 0; // Are any of the values floating point? - if((pos=line.find_first_of("="))!=string::npos) { - strcpy(varname, (line.substr(0,pos)).c_str()); - valuestartpos = pos+1; - currentindex = 0; + Int_t valuestartpos = 0; // Stays zero if no = found + Int_t ttype = 0; // Are any of the values floating point? + if ((pos = line.find_first_of("=")) != string::npos) { + strcpy(varname, (line.substr(0, pos)).c_str()); + valuestartpos = pos + 1; + currentindex = 0; } // If first char after = is a quote, then this is a string assignment - if(line[valuestartpos] == '"' || line[valuestartpos] == '\'') { + if (line[valuestartpos] == '"' || line[valuestartpos] == '\'') { quotechar = line[valuestartpos++]; // Scan until end of line or terminating quote // valuestartpos++; pos = valuestartpos; - while(pos<line.length()) { - if(line[pos++] == quotechar) { // Possibly end of quoted string - if(line[pos] == quotechar) { // Protected quote - pos++; - } else { - pos--; - break; - } - } + while (pos < line.length()) { + if (line[pos++] == quotechar) { // Possibly end of quoted string + if (line[pos] == quotechar) { // Protected quote + pos++; + } else { + pos--; + break; + } + } } - if(TextList) { - // Should check that a numerical assignment doesn't exist, but for - // now, the same variable name can be used for strings and numbers - string varnames(varname); - AddString(varnames, line.substr(valuestartpos,pos-valuestartpos)); + if (TextList) { + // Should check that a numerical assignment doesn't exist, but for + // now, the same variable name can be used for strings and numbers + string varnames(varname); + AddString(varnames, line.substr(valuestartpos, pos - valuestartpos)); } continue; } - TString values((line.substr(valuestartpos)).c_str()); - TObjArray *vararr = values.Tokenize(","); - Int_t nvals = vararr->GetLast()+1; + TString values((line.substr(valuestartpos)).c_str()); + TObjArray* vararr = values.Tokenize(","); + Int_t nvals = vararr->GetLast() + 1; - Int_t* ip=0; - Double_t* fp=0; + Int_t* ip = 0; + Double_t* fp = 0; // or expressions - for(Int_t i=0;(ttype==0&&i<nvals);i++) { - TString valstr = ((TObjString *)vararr->At(i))->GetString(); - if(valstr.IsFloat()) { // Is a number - if(valstr.Contains(".") || valstr.Contains("e",TString::kIgnoreCase)) { - ttype = 1; - break; - } + for (Int_t i = 0; (ttype == 0 && i < nvals); i++) { + TString valstr = ((TObjString*)vararr->At(i))->GetString(); + if (valstr.IsFloat()) { // Is a number + if (valstr.Contains(".") || valstr.Contains("e", TString::kIgnoreCase)) { + ttype = 1; + break; + } } else { - ttype = 2; // Force float if expression or Var - break; + ttype = 2; // Force float if expression or Var + break; } } @@ -382,150 +379,145 @@ The ENGINE CTP support parameter "blocks" which were marked with // // There is some code duplication here. Refactor later - Int_t newlength = currentindex + nvals; - THaVar* existingvar=Find(varname); - if(existingvar) { + Int_t newlength = currentindex + nvals; + THaVar* existingvar = Find(varname); + if (existingvar) { string existingcomment; existingcomment.assign(existingvar->GetTitle()); - if(!existingcomment.empty()) { - current_comment.assign(existingcomment); + if (!existingcomment.empty()) { + current_comment.assign(existingcomment); } - Int_t existingtype=existingvar->GetType(); - Int_t existinglength=existingvar->GetLen(); - if(newlength > existinglength || - (existingtype == kInt && ttype > 0)) { // Length or type change needed - if(newlength < existinglength) newlength = existinglength; - Int_t newtype=-1; - if(ttype>0 || existingtype == kDouble) { - newtype = kDouble; - fp = new Double_t[newlength]; - if(existingtype == kDouble) { - Double_t* existingp= (Double_t*) existingvar->GetValuePointer(); - for(Int_t i=0;i<existinglength;i++) { - fp[i] = existingp[i]; - } - } else if(existingtype == kInt) { - Int_t* existingp= (Int_t*) existingvar->GetValuePointer(); - for(Int_t i=0;i<existinglength;i++) { - fp[i] = existingp[i]; - } - } else { - cout << "Whoops!" << endl; - } - } else if(existingtype == kInt) { // Stays int - newtype = kInt; - ip = new Int_t[newlength]; - Int_t* existingp= (Int_t*) existingvar->GetValuePointer(); - for(Int_t i=0;i<existinglength;i++) { - ip[i] = existingp[i]; - } - } else { - cout << "Whoops!" << endl; - } - // Now copy new values in - for(Int_t i=0;i<nvals;i++) { - TString valstr = ((TObjString *)vararr->At(i))->GetString(); - if(newtype == kInt) { - ip[currentindex+i] = valstr.Atoi(); - } else { - if(valstr.IsFloat()) { - fp[currentindex+i] = valstr.Atof(); - } else { - THaFormula* formula = new THaFormula - ("temp",valstr.Data(), (Bool_t) 0, this, 0); - fp[currentindex+i] = formula->Eval(); - delete formula; - } - } - } - currentindex += nvals; - // Remove old variable and recreate - if(existingtype == kDouble) { - delete [] (Double_t*) existingvar->GetValuePointer(); - } else if (existingtype == kInt) { - delete [] (Int_t*) existingvar->GetValuePointer(); - } - RemoveName(varname); - char *arrayname=new char [strlen(varname)+20]; - sprintf(arrayname,"%s[%d]",varname,newlength); - if(newtype == kInt) { - Define(arrayname, current_comment.c_str(), *ip); - } else { - Define(arrayname, current_comment.c_str(), *fp); - } - delete[] arrayname; + Int_t existingtype = existingvar->GetType(); + Int_t existinglength = existingvar->GetLen(); + if (newlength > existinglength || + (existingtype == kInt && ttype > 0)) { // Length or type change needed + if (newlength < existinglength) + newlength = existinglength; + Int_t newtype = -1; + if (ttype > 0 || existingtype == kDouble) { + newtype = kDouble; + fp = new Double_t[newlength]; + if (existingtype == kDouble) { + Double_t* existingp = (Double_t*)existingvar->GetValuePointer(); + for (Int_t i = 0; i < existinglength; i++) { + fp[i] = existingp[i]; + } + } else if (existingtype == kInt) { + Int_t* existingp = (Int_t*)existingvar->GetValuePointer(); + for (Int_t i = 0; i < existinglength; i++) { + fp[i] = existingp[i]; + } + } else { + cout << "Whoops!" << endl; + } + } else if (existingtype == kInt) { // Stays int + newtype = kInt; + ip = new Int_t[newlength]; + Int_t* existingp = (Int_t*)existingvar->GetValuePointer(); + for (Int_t i = 0; i < existinglength; i++) { + ip[i] = existingp[i]; + } + } else { + cout << "Whoops!" << endl; + } + // Now copy new values in + for (Int_t i = 0; i < nvals; i++) { + TString valstr = ((TObjString*)vararr->At(i))->GetString(); + if (newtype == kInt) { + ip[currentindex + i] = valstr.Atoi(); + } else { + if (valstr.IsFloat()) { + fp[currentindex + i] = valstr.Atof(); + } else { + THaFormula* formula = new THaFormula("temp", valstr.Data(), (Bool_t)0, this, 0); + fp[currentindex + i] = formula->Eval(); + delete formula; + } + } + } + currentindex += nvals; + // Remove old variable and recreate + if (existingtype == kDouble) { + delete[](Double_t*) existingvar->GetValuePointer(); + } else if (existingtype == kInt) { + delete[](Int_t*) existingvar->GetValuePointer(); + } + RemoveName(varname); + char* arrayname = new char[strlen(varname) + 20]; + sprintf(arrayname, "%s[%d]", varname, newlength); + if (newtype == kInt) { + Define(arrayname, current_comment.c_str(), *ip); + } else { + Define(arrayname, current_comment.c_str(), *fp); + } + delete[] arrayname; } else { - // Existing array long enough and of right type, just copy to it. - if(ttype == 0 && existingtype == kInt) { - Int_t* existingp= (Int_t*) existingvar->GetValuePointer(); - for(Int_t i=0;i<nvals;i++) { - TString valstr = ((TObjString *)vararr->At(i))->GetString(); - existingp[currentindex+i] = valstr.Atoi(); - } - } else { - Double_t* existingp= (Double_t*) existingvar->GetValuePointer(); - for(Int_t i=0;i<nvals;i++) { - TString valstr = ((TObjString *)vararr->At(i))->GetString(); - if(valstr.IsFloat()) { - existingp[currentindex+i] = valstr.Atof(); - } else { - THaFormula* formula = new THaFormula - ("temp",valstr.Data(), (Bool_t) 0, this, 0); - existingp[currentindex+i] = formula->Eval(); - delete formula; - } - } - } - currentindex += nvals; + // Existing array long enough and of right type, just copy to it. + if (ttype == 0 && existingtype == kInt) { + Int_t* existingp = (Int_t*)existingvar->GetValuePointer(); + for (Int_t i = 0; i < nvals; i++) { + TString valstr = ((TObjString*)vararr->At(i))->GetString(); + existingp[currentindex + i] = valstr.Atoi(); + } + } else { + Double_t* existingp = (Double_t*)existingvar->GetValuePointer(); + for (Int_t i = 0; i < nvals; i++) { + TString valstr = ((TObjString*)vararr->At(i))->GetString(); + if (valstr.IsFloat()) { + existingp[currentindex + i] = valstr.Atof(); + } else { + THaFormula* formula = new THaFormula("temp", valstr.Data(), (Bool_t)0, this, 0); + existingp[currentindex + i] = formula->Eval(); + delete formula; + } + } + } + currentindex += nvals; } } else { - if(currentindex !=0) { - cout << "currentindex=" << currentindex << " shouldn't be!" << endl; + if (currentindex != 0) { + cout << "currentindex=" << currentindex << " shouldn't be!" << endl; } - if(ttype==0) { - ip = new Int_t[nvals]; + if (ttype == 0) { + ip = new Int_t[nvals]; } else { - fp = new Double_t[nvals]; + fp = new Double_t[nvals]; } - for(Int_t i=0;i<nvals;i++) { - TString valstr = ((TObjString *)vararr->At(i))->GetString(); - if(ttype==0) { - ip[i] = valstr.Atoi(); - } else { - if(valstr.IsFloat()) { - fp[i] = valstr.Atof(); - } else { - THaFormula* formula = new THaFormula - ("temp",valstr.Data(), (Bool_t) 0, this, 0); - fp[i] = formula->Eval(); - delete formula; - } - } + for (Int_t i = 0; i < nvals; i++) { + TString valstr = ((TObjString*)vararr->At(i))->GetString(); + if (ttype == 0) { + ip[i] = valstr.Atoi(); + } else { + if (valstr.IsFloat()) { + fp[i] = valstr.Atof(); + } else { + THaFormula* formula = new THaFormula("temp", valstr.Data(), (Bool_t)0, this, 0); + fp[i] = formula->Eval(); + delete formula; + } + } } currentindex = nvals; - char *arrayname=new char [strlen(varname)+20]; - sprintf(arrayname,"%s[%d]",varname,nvals); - if(ttype==0) { - Define(arrayname, current_comment.c_str(), *ip); + char* arrayname = new char[strlen(varname) + 20]; + sprintf(arrayname, "%s[%d]", varname, nvals); + if (ttype == 0) { + Define(arrayname, current_comment.c_str(), *ip); } else { - Define(arrayname, current_comment.c_str(), *fp); + Define(arrayname, current_comment.c_str(), *fp); } delete[] arrayname; } - delete vararr; // Discard result of Tokenize + delete vararr; // Discard result of Tokenize // cout << line << endl; - } return; - } //_____________________________________________________________________________ -Int_t THcParmList::LoadParmValues(const DBRequest* list, const char* prefix) -{ +Int_t THcParmList::LoadParmValues(const DBRequest* list, const char* prefix) { /** The following example loads several parameters held in the `gHcParms` parameter cache into scalar variables or arrays. @@ -550,77 +542,80 @@ zero), then there will be no error if the parameter is missing. */ - const DBRequest *ti = list; - Int_t cnt=0; - Int_t this_cnt=0; + const DBRequest* ti = list; + Int_t cnt = 0; + Int_t this_cnt = 0; - if( !prefix ) prefix = ""; + if (!prefix) + prefix = ""; - while ( ti && ti->name ) { - string keystr(prefix); keystr.append(ti->name); + while (ti && ti->name) { + string keystr(prefix); + keystr.append(ti->name); const char* key = keystr.c_str(); // cout <<"Now at "<<ti->name<<endl; this_cnt = 0; - if(this->Find(key)) { + if (this->Find(key)) { VarType ty = this->Find(key)->GetType(); - if (ti->nelem>1) { - // it is an array, use the appropriateinterface - switch (ti->type) { - case (kDouble) : - this_cnt = GetArray(key,static_cast<Double_t*>(ti->var),ti->nelem); - break; - case (kInt) : - this_cnt = GetArray(key,static_cast<Int_t*>(ti->var),ti->nelem); - break; - default: - Error("THcParmList","Invalid type to read %s",key); - break; - } + if (ti->nelem > 1) { + // it is an array, use the appropriateinterface + switch (ti->type) { + case (kDouble): + this_cnt = GetArray(key, static_cast<Double_t*>(ti->var), ti->nelem); + break; + case (kInt): + this_cnt = GetArray(key, static_cast<Int_t*>(ti->var), ti->nelem); + break; + default: + Error("THcParmList", "Invalid type to read %s", key); + break; + } } else { - switch (ti->type) { - case (kDouble) : - if(ty == kInt) { - *static_cast<Double_t*>(ti->var)=*(Int_t *)this->Find(key)->GetValuePointer(); - } else if (ty == kDouble) { - *static_cast<Double_t*>(ti->var)=*(Double_t *)this->Find(key)->GetValuePointer(); - } else { - cout << "*** ERROR!!! Type Mismatch " << key << endl; - } - this_cnt=1; - - break; - case (kInt) : - if(ty == kInt) { - *static_cast<Int_t*>(ti->var)=*(Int_t *)this->Find(key)->GetValuePointer(); - } else if (ty == kDouble) { - *static_cast<Int_t*>(ti->var)=TMath::Nint(*(Double_t *)this->Find(key)->GetValuePointer()); - _logger->warn("Rounded {} to nearest integer ",key); - } else { - _logger->error("Type Mismatch {} ",key); - } - this_cnt=1; - break; - default: - _logger->error("THcParmList: Invalid type to read {} ",key); + switch (ti->type) { + case (kDouble): + if (ty == kInt) { + *static_cast<Double_t*>(ti->var) = *(Int_t*)this->Find(key)->GetValuePointer(); + } else if (ty == kDouble) { + *static_cast<Double_t*>(ti->var) = *(Double_t*)this->Find(key)->GetValuePointer(); + } else { + cout << "*** ERROR!!! Type Mismatch " << key << endl; + } + this_cnt = 1; + break; - } + case (kInt): + if (ty == kInt) { + *static_cast<Int_t*>(ti->var) = *(Int_t*)this->Find(key)->GetValuePointer(); + } else if (ty == kDouble) { + *static_cast<Int_t*>(ti->var) = + TMath::Nint(*(Double_t*)this->Find(key)->GetValuePointer()); + _logger->warn("Rounded {} to nearest integer ", key); + } else { + _logger->error("Type Mismatch {} ", key); + } + this_cnt = 1; + break; + default: + _logger->error("THcParmList: Invalid type to read {} ", key); + break; + } } - } else { // See if it is a text variable + } else { // See if it is a text variable const char* value = GetString(key); - if(value) { - this_cnt = 1; - if(ti->type == kString) { - *((string*)ti->var) = string(value); - } else if (ti->type == kTString) { - *((TString*)ti->var) = (TString) value; - } else { - Error("THcParmList","No conversion for strings: %s",key); - } + if (value) { + this_cnt = 1; + if (ti->type == kString) { + *((string*)ti->var) = string(value); + } else if (ti->type == kTString) { + *((TString*)ti->var) = (TString)value; + } else { + Error("THcParmList", "No conversion for strings: %s", key); + } } } - if (this_cnt<=0) { - if ( !ti->optional ) { + if (this_cnt <= 0) { + if (!ti->optional) { string msg = string("Could not find `") + key + "` in database!"; throw std::runtime_error("<THcParmList::LoadParmValues>: " + msg); } @@ -633,67 +628,68 @@ zero), then there will be no error if the parameter is missing. // READING AN ARRAY INTO A C-style ARRAY //_____________________________________________________________________________ -Int_t THcParmList::GetArray(const char* attr, Int_t* array, Int_t size) -{ - return ReadArray(attr,array,size); +Int_t THcParmList::GetArray(const char* attr, Int_t* array, Int_t size) { + return ReadArray(attr, array, size); } //_____________________________________________________________________________ -Int_t THcParmList::GetArray(const char* attr, Double_t* array, Int_t size) -{ - return ReadArray(attr,array,size); +Int_t THcParmList::GetArray(const char* attr, Double_t* array, Int_t size) { + return ReadArray(attr, array, size); } //_____________________________________________________________________________ -template<class T> -Int_t THcParmList::ReadArray(const char* attrC, T* array, Int_t size) -{ +template <class T> +Int_t THcParmList::ReadArray(const char* attrC, T* array, Int_t size) { /** No resizing is done, so only 'size' elements may be stored. */ - Int_t cnt=0; + Int_t cnt = 0; - THaVar *var = Find(attrC); - if(!var) return(cnt); + THaVar* var = Find(attrC); + if (!var) + return (cnt); VarType ty = var->GetType(); - if( ty != kInt && ty != kDouble) { + if (ty != kInt && ty != kDouble) { cout << "*** ERROR: " << attrC << " has unsupported type " << ty << endl; - return(cnt); + return (cnt); } - Int_t sz = var->GetLen(); - const void *vp = var->GetValuePointer(); - if(size != sz) { + Int_t sz = var->GetLen(); + const void* vp = var->GetValuePointer(); + if (size > sz) { + _logger->error("requested {} elements of {} which has only {} elements", size, attrC, sz); + exit(EXIT_FAILURE); + } else if (size < sz) { _logger->warn("requested {} elements of {} which has length {}", size, attrC, sz); } - if(size<sz) sz = size; + if (size < sz) + sz = size; Int_t donint = 0; - if(ty == kDouble && typeid(array[0]) == typeid(Int_t)) { - donint = 1; // Use nint when putting doubles in nint + if (ty == kDouble && typeid(array[0]) == typeid(Int_t)) { + donint = 1; // Use nint when putting doubles in nint cout << "*** WARNING!!! Rounded " << attrC << " elements to nearest integer " << endl; } - for(cnt=0;cnt<sz;cnt++) { - if(ty == kInt) { + for (cnt = 0; cnt < sz; cnt++) { + if (ty == kInt) { array[cnt] = ((Int_t*)vp)[cnt]; - } else - if(donint) { - array[cnt] = TMath::Nint(((Double_t*)vp)[cnt]); - } else { - array[cnt] = ((Double_t*)vp)[cnt]; - } + } else if (donint) { + array[cnt] = TMath::Nint(((Double_t*)vp)[cnt]); + } else { + array[cnt] = ((Double_t*)vp)[cnt]; + } } - return(cnt); + return (cnt); } //_____________________________________________________________________________ -std::string THcParmList::PrintJSON(int run_number ) const { - TIter next(this); +std::string THcParmList::PrintJSON(int run_number) const { + TIter next(this); nlohmann::json j; - while( THaVar* obj = (THaVar*) next() ) { + while (THaVar* obj = (THaVar*)next()) { - if( obj->IsBasic() ) { - if( obj->IsArray() ) { - if( obj->GetLen() == 1 ) { + if (obj->IsBasic()) { + if (obj->IsArray()) { + if (obj->GetLen() == 1) { j[obj->GetName()] = obj->GetValue(); } else { j[obj->GetName()] = obj->GetValues(); @@ -701,133 +697,127 @@ std::string THcParmList::PrintJSON(int run_number ) const { } else { obj->Print(); } - } else { + } else { obj->Print(); } } nlohmann::json jrun; jrun[std::to_string(run_number)] = j; - //std::cout << j.dump(2) << "\n"; + // std::cout << j.dump(2) << "\n"; // write prettified JSON to another file - //std::ofstream o("pretty.json"); - //o << std::setw(4) << jrun << std::endl; + // std::ofstream o("pretty.json"); + // o << std::setw(4) << jrun << std::endl; return jrun.dump(2); } - -void THcParmList::PrintFull( Option_t* option ) const -{ +void THcParmList::PrintFull(Option_t* option) const { THaVarList::PrintFull(option); TextList->Print(); } #ifdef WITH_CCDB //_____________________________________________________________________________ -Int_t THcParmList::OpenCCDB(Int_t runnum) -{ +Int_t THcParmList::OpenCCDB(Int_t runnum) { // Use the Environment variable "CCDB_CONNECTION" as the // connection string const char* connection_string = gSystem->Getenv("CCDB_CONNECTION"); - return(OpenCCDB(runnum,connection_string)); + return (OpenCCDB(runnum, connection_string)); } -Int_t THcParmList::OpenCCDB(Int_t runnum, const char* connection_string) -{ +Int_t THcParmList::OpenCCDB(Int_t runnum, const char* connection_string) { // Connect to a CCDB database pointed to by connection_string - std::string s (connection_string); - CCDB_obj = new SQLiteCalibration(runnum); + std::string s(connection_string); + CCDB_obj = new SQLiteCalibration(runnum); Int_t result = CCDB_obj->Connect(s); - if(!result) return -1; // Need some error codes + if (!result) + return -1; // Need some error codes cout << "Opened " << s << " for run " << runnum << endl; return 0; } -Int_t THcParmList::CloseCCDB() -{ +Int_t THcParmList::CloseCCDB() { delete CCDB_obj; - return(0); + return (0); } -Int_t THcParmList::LoadCCDBDirectory(const char* directory, - const char* prefix) -{ +Int_t THcParmList::LoadCCDBDirectory(const char* directory, const char* prefix) { // Load all parameters in directory // Prepend prefix onto the name of each - std::string dirname (directory); + std::string dirname(directory); - if(dirname[dirname.length()-1]!='/') { + if (dirname[dirname.length() - 1] != '/') { dirname.append("/"); } - Int_t dirlen=dirname.length(); + Int_t dirlen = dirname.length(); vector<string> namepaths; CCDB_obj->GetListOfNamepaths(namepaths); - for(UInt_t iname=0;iname<namepaths.size();iname++) { - std::string varname (namepaths[iname]); - if(varname.compare(0,dirlen,dirname) == 0) { - varname.replace(0,dirlen,prefix); + for (UInt_t iname = 0; iname < namepaths.size(); iname++) { + std::string varname(namepaths[iname]); + if (varname.compare(0, dirlen, dirname) == 0) { + varname.replace(0, dirlen, prefix); // cout << namepaths[iname] << " -> " << varname << endl; // To what extent is there duplication here with Load() method? // Retrieve assignment - Assignment* assignment = CCDB_obj->GetAssignment(namepaths[iname], true); - ConstantsTypeColumn::ColumnTypes ccdbtype=assignment->GetValueType(0); - Int_t ccdbncolumns=assignment->GetColumnsCount(); - Int_t ccdbnrows=assignment->GetRowsCount(); - std::string title = assignment->GetTypeTable()->GetComment(); + Assignment* assignment = CCDB_obj->GetAssignment(namepaths[iname], true); + ConstantsTypeColumn::ColumnTypes ccdbtype = assignment->GetValueType(0); + Int_t ccdbncolumns = assignment->GetColumnsCount(); + Int_t ccdbnrows = assignment->GetRowsCount(); + std::string title = assignment->GetTypeTable()->GetComment(); // Only load single column tables - if(ccdbncolumns == 1) { - - THaVar* existingvar=Find(varname.c_str()); - // Need to append [size] to end of varname - char sizestring[20]; - sprintf(sizestring,"[%d]",ccdbnrows); - std::string size_str (sizestring); - std::string varnamearray (varname); - varnamearray.append(size_str); - - // Select data type - if(ccdbtype==ConstantsTypeColumn::cIntColumn) { - vector<vector<int> > data; - CCDB_obj->GetCalib(data, namepaths[iname]); - - if(existingvar) { - RemoveName(varname.c_str()); - } - - Int_t* ip = new Int_t[data.size()]; - for(UInt_t row=0;row<data.size(); row++) { - ip[row] = data[row][0]; - } - Define(varnamearray.c_str(), title.c_str(), *ip); - - } else if (ccdbtype==ConstantsTypeColumn::cDoubleColumn) { - vector<vector<double> > data; - CCDB_obj->GetCalib(data, namepaths[iname]); - - if(existingvar) { - RemoveName(varname.c_str()); - } - - Double_t* fp = new Double_t[data.size()]; - for(UInt_t row=0;row<data.size(); row++) { - fp[row] = data[row][0]; - } - Define(varnamearray.c_str(), title.c_str(), *fp); - } else if (ccdbtype==ConstantsTypeColumn::cStringColumn) { - if(ccdbnrows > 1) { - cout << namepaths[iname] << ": Only first element of CCDB string array loaded." << endl; - } - vector<vector<string> > data; - CCDB_obj->GetCalib(data, namepaths[iname]); - AddString(varname, data[0][0]); - } else { - cout << namepaths[iname] << ": Unsupported CCDB data type: " << ccdbtype << endl; - } + if (ccdbncolumns == 1) { + + THaVar* existingvar = Find(varname.c_str()); + // Need to append [size] to end of varname + char sizestring[20]; + sprintf(sizestring, "[%d]", ccdbnrows); + std::string size_str(sizestring); + std::string varnamearray(varname); + varnamearray.append(size_str); + + // Select data type + if (ccdbtype == ConstantsTypeColumn::cIntColumn) { + vector<vector<int>> data; + CCDB_obj->GetCalib(data, namepaths[iname]); + + if (existingvar) { + RemoveName(varname.c_str()); + } + + Int_t* ip = new Int_t[data.size()]; + for (UInt_t row = 0; row < data.size(); row++) { + ip[row] = data[row][0]; + } + Define(varnamearray.c_str(), title.c_str(), *ip); + + } else if (ccdbtype == ConstantsTypeColumn::cDoubleColumn) { + vector<vector<double>> data; + CCDB_obj->GetCalib(data, namepaths[iname]); + + if (existingvar) { + RemoveName(varname.c_str()); + } + + Double_t* fp = new Double_t[data.size()]; + for (UInt_t row = 0; row < data.size(); row++) { + fp[row] = data[row][0]; + } + Define(varnamearray.c_str(), title.c_str(), *fp); + } else if (ccdbtype == ConstantsTypeColumn::cStringColumn) { + if (ccdbnrows > 1) { + cout << namepaths[iname] << ": Only first element of CCDB string array loaded." << endl; + } + vector<vector<string>> data; + CCDB_obj->GetCalib(data, namepaths[iname]); + AddString(varname, data[0][0]); + } else { + cout << namepaths[iname] << ": Unsupported CCDB data type: " << ccdbtype << endl; + } } else { - cout << namepaths[iname] << ": Multicolumn CCDB variables not supported" << endl; + cout << namepaths[iname] << ": Multicolumn CCDB variables not supported" << endl; } } } diff --git a/src/THcScalerEvtHandler.cxx b/src/THcScalerEvtHandler.cxx index 1f06497096487779ffd852c868f87086d6b2b366..19a4a6dd4ee2f31d77aed31a381690e428caa499 100644 --- a/src/THcScalerEvtHandler.cxx +++ b/src/THcScalerEvtHandler.cxx @@ -40,7 +40,6 @@ To enable debugging you may try this in the setup script #include <map> #include <sstream> -#include "THcScalerEvtHandler.h" #include "GenScaler.h" #include "Helper.h" #include "Scaler1151.h" @@ -56,6 +55,7 @@ To enable debugging you may try this in the setup script #include "THaVarList.h" #include "THcGlobals.h" #include "THcParmList.h" +#include "THcScalerEvtHandler.h" #include "TMath.h" #include "TNamed.h" #include "TROOT.h" @@ -151,7 +151,7 @@ Int_t THcScalerEvtHandler::ReadDatabase(const TDatime& date) { fBCM_SatQuadratic = new Double_t[fNumBCMs]; fBCM_delta_charge = new Double_t[fNumBCMs]; string bcm_namelist; - DBRequest list2[] = {{"BCM_Gain", fBCM_Gain, kDouble, (UInt_t)fNumBCMs}, + DBRequest list2[] = {{"BCM_Gain", fBCM_Gain, kDouble, (UInt_t)fNumBCMs}, {"BCM_Offset", fBCM_Offset, kDouble, (UInt_t)fNumBCMs}, {"BCM_SatQuadratic", fBCM_SatQuadratic, kDouble, (UInt_t)fNumBCMs, 1}, {"BCM_SatOffset", fBCM_SatOffset, kDouble, (UInt_t)fNumBCMs, 1}, @@ -383,6 +383,7 @@ Int_t THcScalerEvtHandler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync) { size_t ivar = scalerloc[i]->ivar; size_t idx = scalerloc[i]->index; size_t ichan = scalerloc[i]->ichan; + if (evcount == 0) { if (fDebugFile) *fDebugFile << "Debug dvarsFirst " << i << " " << ivar << " " << idx << " " << ichan @@ -421,7 +422,8 @@ Int_t THcScalerEvtHandler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync) { fBCM_Gain[bcm_ind]; dvars[ivar] = dvars[ivar] + - fBCM_SatOffset[bcm_ind] * TMath::Max(dvars[ivar] - fBCM_SatOffset[i], 0.0); + fBCM_SatQuadratic[bcm_ind] * + TMath::Power(TMath::Max(dvars[ivar] - fBCM_SatOffset[bcm_ind], 0.0), 2.0); } if (bcm_ind == fbcm_Current_Threshold_Index) scal_current = dvars[ivar]; @@ -478,7 +480,7 @@ Int_t THcScalerEvtHandler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync) { dvarsFirst[ivar] = dvarsFirst[ivar] + fBCM_SatQuadratic[bcm_ind] * - TMath::Power(TMath::Max(dvars[ivar] - fBCM_SatOffset[i], 0.0), 2.); + TMath::Power(TMath::Max(dvars[ivar] - fBCM_SatOffset[bcm_ind], 0.0), 2.); } if (bcm_ind == fbcm_Current_Threshold_Index) scal_current = dvarsFirst[ivar]; @@ -504,6 +506,7 @@ Int_t THcScalerEvtHandler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync) { } else { cout << "THcScalerEvtHandler:: ERROR:: incorrect index " << ivar << " " << idx << " " << ichan << endl; +>>>>>>> c420edd53c56a5a9d8db08d317c7f15c82de6d17 } } else { // evcount != 0 if (fDebugFile) @@ -588,7 +591,7 @@ Int_t THcScalerEvtHandler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync) { } // printf("event %i index %i fBCMname %s scalerloc %s offset %f gain %f computed //%f\n",evcount, bcm_ind, - //fBCM_Name[bcm_ind],scalerloc[ivar]->name.Data(),fBCM_Offset[bcm_ind],fBCM_Gain[bcm_ind],dvars[ivar]); + // fBCM_Name[bcm_ind],scalerloc[ivar]->name.Data(),fBCM_Offset[bcm_ind],fBCM_Gain[bcm_ind],dvars[ivar]); } if (fDebugFile) *fDebugFile << " dvars " << scalerloc[ivar]->ikind << " " << dvars[ivar] << endl; @@ -638,7 +641,7 @@ Int_t THcScalerEvtHandler::AnalyzeBuffer(UInt_t* rdata, Bool_t onlysync) { evcount = evcount + 1; evcountR = evcount; // - for (size_t j = 0; j < scal_prev_read.size(); j++) + for (size_t j = 0; j < scal_prev_read.size(); j++) scal_prev_read[j] = scal_present_read[j]; // for (size_t j = 0; j < scalers.size(); j++) @@ -703,7 +706,7 @@ THaAnalysisObject::EStatus THcScalerEvtHandler::Init(const TDatime& date) { if (pos1 != minus1 && dbline.size() > 4) { string sdesc = ""; for (size_t j = 5; j < dbline.size(); j++) - sdesc = sdesc + " " + dbline[j]; + sdesc = sdesc + " " + dbline[j]; UInt_t islot = atoi(dbline[1].c_str()); UInt_t ichan = atoi(dbline[2].c_str()); UInt_t ikind = atoi(dbline[3].c_str()); diff --git a/src/THcShowerHit.h b/src/THcShowerHit.h index 7619fb081b27e7a04e204f71cce4ae274977c992..41bfd17c24d4068d3ad8fd8a5961feb858ba9d03 100644 --- a/src/THcShowerHit.h +++ b/src/THcShowerHit.h @@ -7,6 +7,7 @@ #include <iterator> #include <iostream> #include <memory> +#include <vector> #include "TMath.h" using namespace std; diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 6a0afb3ebdafedc26379432edcae7ee373367894..0000000000000000000000000000000000000000 --- a/tests/README.md +++ /dev/null @@ -1,13 +0,0 @@ -Hcana tests -=========== - -## Current tests: - -- ep elastic tests - -## Tests to add: - -- Start time check -- Focal plane times test -- "Tracking efficiency" test -- Invariant mass check (jpsi) diff --git a/tests/elastic_coin_replay.cxx b/tests/elastic_coin_replay.cxx deleted file mode 100644 index 7011fa8a309be4d7572aaf931f7ac7df1496ea50..0000000000000000000000000000000000000000 --- a/tests/elastic_coin_replay.cxx +++ /dev/null @@ -1,296 +0,0 @@ -#include <fmt/core.h> -#include <fmt/ostream.h> -#include <vector> - -#include "TString.h" - -R__LOAD_LIBRARY(libHallC.so) -#include "hcana/HallC_Data.h" -#include "DecData.h" -//R__LOAD_LIBRARY(libScandalizer.so) -//#include "monitor/DetectorDisplay.h" -//#include "monitor/DisplayPlots.h" -//#include "monitor/MonitoringDisplay.h" -//#include "scandalizer/PostProcessors.h" -//#include "scandalizer/ScriptHelpers.h" -// -//#include "THaPostProcess.h" -//#include "monitor/ExperimentMonitor.h" -//#include "scandalizer/PostProcessors.h" -#include "THcAnalyzer.h" -#include "THaCut.h" -#include "THcGlobals.h" -#include "THcHallCSpectrometer.h" -#include "THcDetectorMap.h" -#include "THcCherenkov.h" -#include "THcDC.h" -#include "THcHodoscope.h" -#include "THcParmList.h" -#include "THaGoldenTrack.h" -#include "THcHodoEff.h" -#include "THcScalerEvtHandler.h" -#include "THcShower.h" -#include "THcReactionPoint.h" -#include "THcExtTarCor.h" -#include "THcRasteredBeam.h" -#include "THcRun.h" -#include "THcCoinTime.h" -#include "THcConfigEvtHandler.h" -#include "THcTrigDet.h" -#include "THcTrigApp.h" -#include "THcSecondaryKine.h" -#include "THcAerogel.h" -#include "THcPrimaryKine.h" -#include "THaReactionPoint.h" - - - -void elastic_coin_replay(Int_t RunNumber = 0, Int_t MaxEvent = -1) { - using namespace std; - - // Get RunNumber and MaxEvent if not provided. - if( RunNumber<=0 ) { - std::exit(-1); - } - - // Create file name patterns. - const char* RunFileNamePattern = "coin_all_%05d.dat"; - vector<TString> pathList; - pathList.push_back("."); - pathList.push_back("./raw"); - pathList.push_back("./raw/../raw.copiedtotape"); - pathList.push_back("./cache"); - - //const char* RunFileNamePattern = "raw/coin_all_%05d.dat"; - const char* ROOTFileNamePattern = "ROOTfiles/coin_replay_production_%d_%d.root"; - - // Load global parameters - gHcParms->Define("gen_run_number", "Run Number", RunNumber); - gHcParms->AddString("g_ctp_database_filename", "DBASE/COIN/standard.database"); - gHcParms->Load(gHcParms->GetString("g_ctp_database_filename"), RunNumber); - gHcParms->Load(gHcParms->GetString("g_ctp_parm_filename")); - gHcParms->Load(gHcParms->GetString("g_ctp_kinematics_filename"), RunNumber); - // Load params for COIN trigger configuration - gHcParms->Load("PARAM/TRIG/tcoin.param"); - // Load fadc debug parameters - gHcParms->Load("PARAM/HMS/GEN/h_fadc_debug.param"); - gHcParms->Load("PARAM/SHMS/GEN/p_fadc_debug.param"); - - // const char* CurrentFileNamePattern = "low_curr_bcm/bcmcurrent_%d.param"; - // gHcParms->Load(Form(CurrentFileNamePattern, RunNumber)); - - // Load the Hall C detector map - gHcDetectorMap = new THcDetectorMap(); - gHcDetectorMap->Load("MAPS/COIN/DETEC/coin.map"); - - // Dec data - gHaApps->Add(new Podd::DecData("D","Decoder raw data")); - //=:=:=:= - // SHMS - //=:=:=:= - - // Set up the equipment to be analyzed. - THcHallCSpectrometer* SHMS = new THcHallCSpectrometer("P", "SHMS"); - SHMS->SetEvtType(1); - SHMS->AddEvtType(4); - SHMS->AddEvtType(5); - SHMS->AddEvtType(6); - SHMS->AddEvtType(7); - gHaApps->Add(SHMS); - // Add Noble Gas Cherenkov to SHMS apparatus - THcCherenkov* pngcer = new THcCherenkov("ngcer", "Noble Gas Cherenkov"); - SHMS->AddDetector(pngcer); - // Add drift chambers to SHMS apparatus - THcDC* pdc = new THcDC("dc", "Drift Chambers"); - SHMS->AddDetector(pdc); - // Add hodoscope to SHMS apparatus - THcHodoscope* phod = new THcHodoscope("hod", "Hodoscope"); - SHMS->AddDetector(phod); - // Add Heavy Gas Cherenkov to SHMS apparatus - THcCherenkov* phgcer = new THcCherenkov("hgcer", "Heavy Gas Cherenkov"); - SHMS->AddDetector(phgcer); - // Add Aerogel Cherenkov to SHMS apparatus - THcAerogel* paero = new THcAerogel("aero", "Aerogel"); - SHMS->AddDetector(paero); - // Add calorimeter to SHMS apparatus - THcShower* pcal = new THcShower("cal", "Calorimeter"); - SHMS->AddDetector(pcal); - - // THcBCMCurrent* hbc = new THcBCMCurrent("H.bcm", "BCM current check"); - // gHaPhysics->Add(hbc); - - // Add rastered beam apparatus - THaApparatus* pbeam = new THcRasteredBeam("P.rb", "Rastered Beamline"); - gHaApps->Add(pbeam); - // Add physics modules - // Calculate reaction point - THcReactionPoint* prp = new THcReactionPoint("P.react", "SHMS reaction point", "P", "P.rb"); - gHaPhysics->Add(prp); - // Calculate extended target corrections - THcExtTarCor* pext = new THcExtTarCor("P.extcor", "HMS extended target corrections", "P", "P.react"); - gHaPhysics->Add(pext); - // Calculate golden track quantites - THaGoldenTrack* pgtr = new THaGoldenTrack("P.gtr", "SHMS Golden Track", "P"); - gHaPhysics->Add(pgtr); - // Calculate the hodoscope efficiencies - THcHodoEff* peff = new THcHodoEff("phodeff", "SHMS hodo efficiency", "P.hod"); - gHaPhysics->Add(peff); - - // Add event handler for scaler events - THcScalerEvtHandler* pscaler = new THcScalerEvtHandler("P", "Hall C scaler event type 1"); - pscaler->AddEvtType(1); - pscaler->AddEvtType(4); - pscaler->AddEvtType(5); - pscaler->AddEvtType(6); - pscaler->AddEvtType(7); - pscaler->AddEvtType(129); - pscaler->SetDelayedType(129); - pscaler->SetUseFirstEvent(kTRUE); - gHaEvtHandlers->Add(pscaler); - - //=:=:= - // HMS - //=:=:= - - // Set up the equipment to be analyzed. - THcHallCSpectrometer* HMS = new THcHallCSpectrometer("H", "HMS"); - HMS->SetEvtType(2); - HMS->AddEvtType(4); - HMS->AddEvtType(5); - HMS->AddEvtType(6); - HMS->AddEvtType(7); - gHaApps->Add(HMS); - // Add drift chambers to HMS apparatus - THcDC* hdc = new THcDC("dc", "Drift Chambers"); - HMS->AddDetector(hdc); - // Add hodoscope to HMS apparatus - THcHodoscope* hhod = new THcHodoscope("hod", "Hodoscope"); - HMS->AddDetector(hhod); - // Add Cherenkov to HMS apparatus - THcCherenkov* hcer = new THcCherenkov("cer", "Heavy Gas Cherenkov"); - HMS->AddDetector(hcer); - // Add Aerogel Cherenkov to HMS apparatus - // THcAerogel* haero = new THcAerogel("aero", "Aerogel"); - // HMS->AddDetector(haero); - // Add calorimeter to HMS apparatus - THcShower* hcal = new THcShower("cal", "Calorimeter"); - HMS->AddDetector(hcal); - - // Add rastered beam apparatus - THaApparatus* hbeam = new THcRasteredBeam("H.rb", "Rastered Beamline"); - gHaApps->Add(hbeam); - // Add physics modules - // Calculate reaction point - THcReactionPoint* hrp = new THcReactionPoint("H.react", "HMS reaction point", "H", "H.rb"); - gHaPhysics->Add(hrp); - // Calculate extended target corrections - THcExtTarCor* hext = new THcExtTarCor("H.extcor", "HMS extended target corrections", "H", "H.react"); - gHaPhysics->Add(hext); - // Calculate golden track quantities - THaGoldenTrack* hgtr = new THaGoldenTrack("H.gtr", "HMS Golden Track", "H"); - gHaPhysics->Add(hgtr); - // Calculate the hodoscope efficiencies - THcHodoEff* heff = new THcHodoEff("hhodeff", "HMS hodo efficiency", "H.hod"); - gHaPhysics->Add(heff); - - // Add event handler for scaler events - THcScalerEvtHandler *hscaler = new THcScalerEvtHandler("H", "Hall C scaler event type 4"); - hscaler->AddEvtType(2); - hscaler->AddEvtType(4); - hscaler->AddEvtType(5); - hscaler->AddEvtType(6); - hscaler->AddEvtType(7); - hscaler->AddEvtType(129); - hscaler->SetDelayedType(129); - hscaler->SetUseFirstEvent(kTRUE); - gHaEvtHandlers->Add(hscaler); - - //=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= - // Kinematics Modules - //=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= - - // Add Physics Module to calculate primary (scattered electrons) beam kinematics - THcPrimaryKine* hkin_primary = new THcPrimaryKine("H.kin.primary", "HMS Single Arm Kinematics", "H", "H.rb"); - gHaPhysics->Add(hkin_primary); - // Add Physics Module to calculate secondary (scattered hadrons) beam kinematics - THcSecondaryKine* pkin_secondary = new THcSecondaryKine("P.kin.secondary", "SHMS Single Arm Kinematics", "P", "H.kin.primary"); - gHaPhysics->Add(pkin_secondary); - - //=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= - // Global Objects & Event Handlers - //=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= - - // Add trigger apparatus - THaApparatus* TRG = new THcTrigApp("T", "TRG"); - gHaApps->Add(TRG); - // Add trigger detector to trigger apparatus - THcTrigDet* coin = new THcTrigDet("coin", "Coincidence Trigger Information"); - // Suppress missing reference time warnings for these event types - coin->SetEvtType(1); - coin->AddEvtType(2); - TRG->AddDetector(coin); - - - //Add coin physics module THcCoinTime::THcCoinTime (const char *name, const char* description, const char* hadArmName, - // const char* elecArmName, const char* coinname) : - THcCoinTime* coinTime = new THcCoinTime("CTime", "Coincidende Time Determination", "P", "H", "T.coin"); - gHaPhysics->Add(coinTime); - - // Add event handler for prestart event 125. - THcConfigEvtHandler* ev125 = new THcConfigEvtHandler("HC", "Config Event type 125"); - gHaEvtHandlers->Add(ev125); - // Add event handler for EPICS events - THaEpicsEvtHandler* hcepics = new THaEpicsEvtHandler("epics", "HC EPICS event type 180"); - gHaEvtHandlers->Add(hcepics); - - // Set up the analyzer - we use the standard one, - // but this could be an experiment-specific one as well. - // The Analyzer controls the reading of the data, executes - // tests/cuts, loops over Acpparatus's and PhysicsModules, - // and executes the output routines. - THcAnalyzer* analyzer = new THcAnalyzer; - - // A simple event class to be output to the resulting tree. - // Creating your own descendant of THaEvent is one way of - // defining and controlling the output. - THaEvent* event = new THaEvent; - - // Define the run(s) that we want to analyze. - // We just set up one, but this could be many. - THcRun* run = new THcRun( pathList, Form(RunFileNamePattern, RunNumber) ); - - // Set to read in Hall C run database parameters - run->SetRunParamClass("THcRunParameters"); - - // Eventually need to learn to skip over, or properly analyze the pedestal events - run->SetEventRange(1, MaxEvent); // Physics Event number, does not include scaler or control events. - run->SetNscan(1); - run->SetDataRequired(0x7); - run->Print(); - - // Define the analysis parameters - TString ROOTFileName = Form(ROOTFileNamePattern, RunNumber, MaxEvent); - analyzer->SetCountMode(2); // 0 = counter is # of physics triggers - // 1 = counter is # of all decode reads - // 2 = counter is event number - - analyzer->SetEvent(event); - // Set EPICS event type - analyzer->SetEpicsEvtType(180); - // Define crate map - analyzer->SetCrateMapFileName("MAPS/db_cratemap.dat"); - // Define output ROOT file - analyzer->SetOutFile(ROOTFileName.Data()); - // Define DEF-file+ - analyzer->SetOdefFile("DEF-files/COIN/PRODUCTION/coin_production_hElec_pProt.def"); - // Define cuts file - analyzer->SetCutFile("DEF-files/COIN/PRODUCTION/CUTS/coin_production_cuts.def"); // optional - // File to record accounting information for cuts - analyzer->SetSummaryFile(Form("REPORT_OUTPUT/COIN/PRODUCTION/summary_production_%d_%d.report", RunNumber, MaxEvent)); // optional - // Start the actual analysis. - analyzer->Process(run); - // Create report file from template - analyzer->PrintReport("TEMPLATES/COIN/PRODUCTION/coin_production.template", - Form("REPORT_OUTPUT/COIN/PRODUCTION/replay_coin_production_%d_%d.report", RunNumber, MaxEvent)); // optional - -} diff --git a/tests/elastic_test.cxx b/tests/elastic_test.cxx deleted file mode 100644 index 4c9ad79f09c3cfefec9d399f8fd68d6718ee3551..0000000000000000000000000000000000000000 --- a/tests/elastic_test.cxx +++ /dev/null @@ -1,446 +0,0 @@ -#include "nlohmann/json.hpp" -#include <cmath> -#include <iostream> - -#include "ROOT/RDataFrame.hxx" -#include "ROOT/RVec.hxx" - -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "Math/VectorUtil.h" -#include "TCanvas.h" -#include "TLatex.h" -#include "TStyle.h" -#include "TSystem.h" -R__LOAD_LIBRARY(libMathMore.so) -R__LOAD_LIBRARY(libGenVector.so) - -R__LOAD_LIBRARY(libfmt.so) -#include "fmt/core.h" - -#include "THStack.h" - -#ifdef __cpp_lib_filesystem -#include <filesystem> -namespace fs = std::filesystem; -#else -#include <experimental/filesystem> -namespace fs = std::experimental::filesystem; -#endif - -using RDFNode = decltype(ROOT::RDataFrame{0}.Filter("")); -using Histo1DProxy = - decltype(ROOT::RDataFrame{0}.Histo1D(ROOT::RDF::TH1DModel{"", "", 128u, 0., 0.}, "")); - -struct RDFInfo { - RDFNode& df; - const std::string title; - RDFInfo(RDFNode& df, std::string_view title) : df{df}, title{title} {} -}; - -constexpr const double M_P = .938272; -constexpr const double M_P2 = M_P * M_P; -constexpr const double M_pion = 0.139; -constexpr const double M_pion2 = M_pion * M_pion; -constexpr const double M_e = .000511; - -// ================================================================================= -// Cuts -// ================================================================================= -std::string goodTrackSHMS = "P.gtr.dp > -10 && P.gtr.dp < 22"; -std::string goodTrackHMS = "H.gtr.dp > -8 && H.gtr.dp < 8"; - -std::string piCutSHMS = "P.cal.etottracknorm<1.0"; -//std::string piCutSHMS = "P.aero.npeSum > 1.0 && P.cal.eprtracknorm < 0.2 && P.cal.etottracknorm<1.0"; - -std::string eCutHMS = "H.cal.etottracknorm > 0.50 && H.cal.etottracknorm < 2. && " - "H.cer.npeSum > 1."; - -std::string epiCut = "P.aero.npeSum > 1.0 && P.cal.eprtracknorm < 0.2 && " - "H.cer.npeSum > 1.0 && H.cal.etottracknorm > 0.6 && " - "H.cal.etottracknorm < 2.0 && P.cal.etottracknorm<1.0"; - -using Pvec3D = ROOT::Math::XYZVector; -using Pvec4D = ROOT::Math::PxPyPzMVector; - -// ================================================================================= -// reconstruction -// ================================================================================= -auto p_pion = [](double px, double py, double pz) { - return Pvec4D{px * 0.996, py * 0.996, pz * 0.996, M_e}; -}; -auto p_electron = [](double px, double py, double pz) { - return Pvec4D{px * 0.994, py * 0.994, pz * 0.994, M_e}; -}; -auto t = [](const double Egamma, Pvec4D& jpsi) { - Pvec4D beam{0, 0, Egamma, 0}; - return (beam - jpsi).M2(); -}; - -bool root_file_exists(std::string rootfile) { - bool found_good_file = false; - if (!gSystem->AccessPathName(rootfile.c_str())) { - TFile file(rootfile.c_str()); - if (file.IsZombie()) { - std::cout << rootfile << " is a zombie.\n"; - std::cout - << " Did your replay finish? Check that the it is done before running this script.\n"; - return false; - // return; - } else { - std::cout << " using : " << rootfile << "\n"; - return true; - } - } - return false; -} - -void elastic_test(int RunNumber = 6012, int nevents = 50000, int prompt = 0, int update = 0, - int default_count_goal = 10000, int redo_timing = 0) { - - // =============================================================================================== - // Initialization - // =============================================================================================== - using nlohmann::json; - json j; - { - std::ifstream json_input_file("db2/run_list_coin.json"); - try { - json_input_file >> j; - } catch (json::parse_error) { - std::cerr << "error: json file, db2/run_list.json, is incomplete or has broken syntax.\n"; - std::quick_exit(-127); - } - } - - auto runnum_str = std::to_string(RunNumber); - if (j.find(runnum_str) == j.end()) { - std::cout << "Run " << RunNumber << " not found in db2/run_list_coin.json\n"; - std::cout << "Check that run number and replay exists. \n"; - std::cout << "If problem persists please contact Sylvester (217-848-0565)\n"; - } - double P0_shms_setting = j[runnum_str]["spectrometers"]["shms_momentum"].get<double>(); - double P0_shms = std::abs(P0_shms_setting); - - bool found_good_file = false; - - std::string rootfile = - fmt::format("full_online/coin_replay_production_{}_{}.root", RunNumber, nevents); - found_good_file = root_file_exists(rootfile.c_str()); - if (!found_good_file) { - rootfile = - fmt::format("ROOTfiles_volatile/coin_replay_production_{}_{}.root", RunNumber, nevents); - found_good_file = root_file_exists(rootfile.c_str()); - } - if (!found_good_file) { - rootfile = fmt::format("ROOTfiles_csv/coin_replay_production_{}_{}.root", RunNumber, nevents); - found_good_file = root_file_exists(rootfile.c_str()); - } - if (!found_good_file) { - rootfile = fmt::format("ROOTfiles/coin_replay_production_{}_{}.root", RunNumber, nevents); - found_good_file = root_file_exists(rootfile.c_str()); - } - if (!found_good_file) { - std::cout << " Error: suitable root file not found\n"; - return; - } - - // =============================================================================================== - // Dataframe - // =============================================================================================== - - ROOT::EnableImplicitMT(24); - - //--------------------------------------------------------------------------- - // Detector tree - ROOT::RDataFrame d("T", rootfile); - - //// SHMS Scaler tree - //ROOT::RDataFrame d_sh("TSP", rootfile); - //// int N_scaler_events = *(d_sh.Count()); - - auto d_coin = d.Filter("fEvtHdr.fEvtType == 4"); - - // Good track cuts - auto dHMSGoodTrack = d_coin.Filter(goodTrackHMS); - auto dSHMSGoodTrack = d_coin.Filter(goodTrackSHMS); - auto dCOINGoodTrack = dHMSGoodTrack.Filter(goodTrackSHMS) - .Define("p_electron", p_electron, {"H.gtr.px", "H.gtr.py", "H.gtr.pz"}) - .Define("p_pion", p_pion, {"P.gtr.px", "P.gtr.py", "P.gtr.pz"}); - // PID cuts - auto dHMSEl = dHMSGoodTrack.Filter(eCutHMS); - auto dSHMSEl = dSHMSGoodTrack.Filter(piCutSHMS); - auto dCOINEl = dCOINGoodTrack.Filter(eCutHMS + " && " + piCutSHMS); - //.Filter( - // [=](double npe, double dp) { - // double p_track = P0_shms * (100.0 + dp) / 100.0; - // // no cerenkov cut needed when momentum is below 2.8 GeV/c - // if (p_track < 2.8) { - // return true; - // } - // return npe > 1.0; - // }, - // {"P.hgcer.npeSum", "P.gtr.dp"}); - - // Timing cuts - // Find the timing peak - // Find the coin peak - double coin_peak_center = 0; - if (redo_timing) { - auto h_coin_time = - dCOINEl.Histo1D({"coin_time", "coin_time", 8000, 0, 1000}, "CTime.ePositronCoinTime_ROC2"); - h_coin_time->DrawClone(); - int coin_peak_bin = h_coin_time->GetMaximumBin(); - coin_peak_center = h_coin_time->GetBinCenter(coin_peak_bin); - std::cout << "COINCIDENCE time peak found at: " << coin_peak_center << std::endl; - } else { - //coin_peak_center = 43.0; // run 7240-7241 - coin_peak_center = 23.0; // run 6012 - std::cout << "COINCIDENCE time peak: using pre-calculated value at: " << coin_peak_center - << std::endl; - ; - } - // timing cut lambdas - // TODO: evaluate timing cut and offset for random background - auto timing_cut = [=](double coin_time) { return std::abs(coin_time - coin_peak_center) < 2.; }; - // anti-timing set to 5x width of regular - auto anti_timing_cut = [=](double coin_time) { - return std::abs(coin_time - coin_peak_center - 28.) < 10.; - }; - - // timing counts - auto dHMSElInTime = dHMSEl.Filter(timing_cut, {"CTime.ePositronCoinTime_ROC2"}); - auto dHMSElRandom = dHMSEl.Filter(anti_timing_cut, {"CTime.ePositronCoinTime_ROC2"}); - auto dSHMSElInTime = dSHMSEl.Filter(timing_cut, {"CTime.ePositronCoinTime_ROC2"}); - auto dSHMSElRandom = dSHMSEl.Filter(anti_timing_cut, {"CTime.ePositronCoinTime_ROC2"}); - - auto dCOINElInTime = dCOINEl.Filter(timing_cut, {"CTime.ePiCoinTime_ROC2"}); - auto dCOINElRandom = dCOINEl.Filter(anti_timing_cut, {"CTime.ePiCoinTime_ROC2"}); - - // Output root file - //auto out_file = - // new TFile(fmt::format("monitoring/{}/good_csv_counter.root", RunNumber).c_str(), "UPDATE"); - //out_file->cd(); - - // ========================================================================================= - // Histograms - // ========================================================================================= - // 2D correlations - auto hTheta2DNoCuts = d_coin.Histo2D( - {"theta2D", "No cuts;#theta_{SHMS};#theta_{HMS};#counts", 50, -.1, .1, 50, -.1, .1}, - "P.gtr.th", "H.gtr.th"); - auto hTheta2DTracking = dCOINGoodTrack.Histo2D( - {"theta2D", "Cuts: tracking;#theta_{SHMS};#theta_{HMS};#counts", 50, -.1, .1, 50, -.1, .1}, - "P.gtr.th", "H.gtr.th"); - auto hTheta2DPID = - dCOINEl.Histo2D({"theta2D", "Cuts: tracking+PID;#theta_{SHMS};#theta_{HMS};#counts", 50, -.1, - .1, 50, -.1, .1}, - "P.gtr.th", "H.gtr.th"); - auto hTheta2DTiming = - dCOINElInTime.Histo2D({"theta2D", "Cuts: tracking+PID;#theta_{SHMS};#theta_{HMS};#counts", 50, - -.1, .1, 50, -.1, .1}, - "P.gtr.th", "H.gtr.th"); - // timing - auto hCoinTimeNoCuts = - d_coin.Histo1D({"coin_time.NoCuts", "No Cuts;coin_time;counts", 8000, 0, 1000}, - "CTime.ePositronCoinTime_ROC2"); - auto hCoinTimeTracking = dCOINGoodTrack.Histo1D( - {"coin_time.Tracking", "Cuts: Tracking;coin_time;counts", 8000, 0, 1000}, - "CTime.ePositronCoinTime_ROC2"); - auto hCoinTimePID = - dCOINEl.Histo1D({"coin_time.PID", "Cuts: Tracking+PID;coin_time;counts", 8000, 0, 1000}, - "CTime.ePositronCoinTime_ROC2"); - auto hCoinTimeTiming = dCOINElInTime.Histo1D( - {"coin_time.Timing", "Cuts: Tracking+PID+Timing;coin_time;counts", 8000, 0, 1000}, - "CTime.ePositronCoinTime_ROC2"); - - auto hRandCoinTimePID = dCOINElRandom.Histo1D( - {"rand_coin_time.PID", "Cuts: Tracking+PID;coin_time;counts", 8000, 0, 1000}, - "CTime.ePositronCoinTime_ROC2"); - - // P.gtr.dp - auto hPdpNoCuts = - d_coin.Histo1D({"P.gtr.dp.NoCuts", "No Cuts;#deltap [%];counts", 200, -30, 40}, "P.gtr.dp"); - auto hPdpTracking = dSHMSGoodTrack.Histo1D( - {"P.gtr.dp.Tracking", "Cuts: Tracking;#deltap [%];counts", 200, -30, 40}, "P.gtr.dp"); - auto hPdpPID = dSHMSEl.Histo1D( - {"P.gtr.dp.PID", "Cuts: Tracking+PID;#deltap [%];counts", 200, -30, 40}, "P.gtr.dp"); - auto hPdpTiming = dSHMSElInTime.Histo1D( - {"P.gtr.dp.Timing", "Cuts: Tracking+PID+Timing;#deltap [%];counts", 200, -30, 40}, - "P.gtr.dp"); - // P.gtr.th - auto hPthNoCuts = d_coin.Histo1D( - {"P.gtr.th.NoCuts", "No Cuts;#theta_{SHMS};counts", 200, -0.1, 0.1}, "P.gtr.th"); - auto hPthTracking = dSHMSGoodTrack.Histo1D( - {"P.gtr.th.Tracking", "Cuts: Tracking;#theta_{SHMS};counts", 200, -0.1, 0.1}, "P.gtr.th"); - auto hPthPID = dSHMSEl.Histo1D( - {"P.gtr.th.PID", "Cuts: Tracking+PID;#theta_{SHMS};counts", 200, -0.1, 0.1}, "P.gtr.th"); - auto hPthTiming = dSHMSElInTime.Histo1D( - {"P.gtr.th.Timing", "Cuts: Tracking+PID+Timing;#theta_{SHMS};counts", 200, -0.1, 0.1}, - "P.gtr.th"); - // P.gtr.ph - auto hPphNoCuts = - d_coin.Histo1D({"P.gtr.ph.NoCuts", "No Cuts;#phi_{SHMS};counts", 200, -0.1, 0.1}, "P.gtr.ph"); - auto hPphTracking = dSHMSGoodTrack.Histo1D( - {"P.gtr.ph.Tracking", "Cuts: Tracking;#phi_{SHMS};counts", 200, -0.1, 0.1}, "P.gtr.ph"); - auto hPphPID = dSHMSEl.Histo1D( - {"P.gtr.ph.PID", "Cuts: Tracking+PID;#phi_{SHMS};counts", 200, -0.1, 0.1}, "P.gtr.ph"); - auto hPphTiming = dSHMSElInTime.Histo1D( - {"P.gtr.ph.Timing", "Cuts: Tracking+PID+Timing;#phi_{SHMS};counts", 200, -0.1, 0.1}, - "P.gtr.ph"); - // P.gtr.y - auto hPyNoCuts = - d_coin.Histo1D({"P.gtr.y.NoCuts", "No Cuts;ytar;counts", 200, -10., 10.}, "P.gtr.y"); - auto hPyTracking = dSHMSGoodTrack.Histo1D( - {"P.gtr.y.Tracking", "Cuts: Tracking;ytar;counts", 200, -10., 10.}, "P.gtr.y"); - auto hPyPID = - dSHMSEl.Histo1D({"P.gtr.y.PID", "Cuts: Tracking+PID;ytar;counts", 200, -10., 10.}, "P.gtr.y"); - auto hPyTiming = dSHMSElInTime.Histo1D( - {"P.gtr.y.Timing", "Cuts: Tracking+PID+Timing;ytar;counts", 200, -10., 10.}, "P.gtr.y"); - // P.cal.etottracknorm - auto hPcalEPNoCuts = - d_coin.Histo1D({"P.cal.etottracknorm.NoCuts", "No Cuts;SHMS E/P;counts", 200, -.5, 1.5}, - "P.cal.etottracknorm"); - auto hPcalEPTracking = dSHMSGoodTrack.Histo1D( - {"P.cal.etottracknorm.Tracking", "Cuts: Tracking;SHMS E/P;counts", 200, -.5, 1.5}, - "P.cal.etottracknorm"); - auto hPcalEPPID = dSHMSEl.Histo1D( - {"P.cal.etottracknorm.PID", "Cuts: Tracking+PID;SHMS E/P;counts", 200, -.5, 1.5}, - "P.cal.etottracknorm"); - auto hPcalEPAll = dCOINElInTime.Histo1D( - {"P.cal.etottracknorm.All", "Cuts: Tracking+PID+Coincidence;SHMS E/P;counts", 200, -.5, 1.5}, - "P.cal.etottracknorm"); - // P.ngcer.npeSum - auto hPcerNpheNoCuts = d_coin.Histo1D( - {"P.ngcer.npeSum.NoCuts", "No Cuts;SHMS NGC #phe;counts", 200, -5, 76}, "P.ngcer.npeSum"); - auto hPcerNpheTracking = dSHMSGoodTrack.Histo1D( - {"P.ngcer.npeSum.Tracking", "Cuts: Tracking;SHMS NGC #phe;counts", 200, -5, 76}, - "P.ngcer.npeSum"); - auto hPcerNphePID = dSHMSEl.Histo1D( - {"P.ngcer.npeSum.PID", "Cuts: Tracking+PID;SHMS NGC #phe;counts", 200, -5, 76}, - "P.ngcer.npeSum"); - auto hPcerNpheAll = dCOINElInTime.Histo1D( - {"P.ngcer.npeSum.All", "Cuts: Tracking+PID+Coincidence;SHMS NGC #phe;counts", 200, -5, 76}, - "P.ngcer.npeSum"); - // P.hgcer.npeSum - auto hPhgcerNpheNoCuts = d_coin.Histo1D( - {"P.hgcer.npeSum.NoCuts", "No Cuts;SHMS HGC #phe;counts", 200, -5, 76}, "P.hgcer.npeSum"); - auto hPhgcerNpheTracking = dSHMSGoodTrack.Histo1D( - {"P.hgcer.npeSum.Tracking", "Cuts: Tracking;SHMS HGC #phe;counts", 200, -5, 76}, - "P.hgcer.npeSum"); - auto hPhgcerNphePID = dSHMSEl.Histo1D( - {"P.hgcer.npeSum.PID", "Cuts: Tracking+PID;SHMS HGC #phe;counts", 200, -5, 76}, - "P.hgcer.npeSum"); - auto hPhgcerNpheAll = dCOINElInTime.Histo1D( - {"P.hgcer.npeSum.All", "Cuts: Tracking+PID+Coincidence;SHMS HGC #phe;counts", 200, -5, 76}, - "P.hgcer.npeSum"); - // H.cal.etottracknorm - auto hHcalEPNoCuts = - d_coin.Histo1D({"H.cal.etottracknorm.NoCuts", "No Cuts;HMS E/P;counts", 200, -.5, 1.5}, - "H.cal.etottracknorm"); - auto hHcalEPTracking = dHMSGoodTrack.Histo1D( - {"H.cal.etottracknorm.Tracking", "Cuts: Tracking;HMS E/P;counts", 200, -.5, 1.5}, - "H.cal.etottracknorm"); - auto hHcalEPPID = dHMSEl.Histo1D( - {"H.cal.etottracknorm.PID", "Cuts: Tracking+PID;HMS E/P;counts", 200, -.5, 1.5}, - "H.cal.etottracknorm"); - auto hHcalEPAll = dCOINElInTime.Histo1D( - {"H.cal.etottracknorm.All", "Cuts: Tracking+PID+Coincidence;HMS E/P;counts", 200, -.5, 1.5}, - "H.cal.etottracknorm"); - // H.cer.npeSum - auto hHcerNpheNoCuts = d_coin.Histo1D( - {"H.cer.npeSum.NoCuts", "No Cuts;HMS Cer #phe;counts", 200, -1, 15}, "H.cer.npeSum"); - auto hHcerNpheTracking = dHMSGoodTrack.Histo1D( - {"H.cer.npeSum.Tracking", "Cuts: Tracking;HMS Cer #phe;counts", 200, -1, 15}, "H.cer.npeSum"); - auto hHcerNphePID = dHMSEl.Histo1D( - {"H.cer.npeSum.PID", "Cuts: Tracking+PID+Coincidence;HMS Cer #phe;counts", 200, -1, 15}, - "H.cer.npeSum"); - auto hHcerNpheAll = dCOINElInTime.Histo1D( - {"H.cer.npeSum.PID", "Cuts: Tracking+PID+Coincidence;HMS Cer #phe;counts", 200, -1, 15}, - "H.cer.npeSum"); - // H.gtr.dp - auto hHdpNoCuts = - d_coin.Histo1D({"H.gtr.dp.NoCuts", "No Cuts;#deltap [%];counts", 200, -30, 40}, "H.gtr.dp"); - auto hHdpTracking = dHMSGoodTrack.Histo1D( - {"H.gtr.dp.Tracking", "Cuts: Tracking;#deltap [%];counts", 200, -30, 40}, "H.gtr.dp"); - auto hHdpPID = dHMSEl.Histo1D( - {"H.gtr.dp.PID", "Cuts: Tracking+PID;#deltap [%];counts", 200, -30, 40}, "H.gtr.dp"); - auto hHdpTiming = dHMSElInTime.Histo1D( - {"H.gtr.dp.Timing", "Cuts: Tracking+PID+Timing;#deltap [%];counts", 200, -30, 40}, - "H.gtr.dp"); - // H.gtr.th - auto hHthNoCuts = d_coin.Histo1D( - {"H.gtr.th.NoCuts", "No Cuts;#theta_{HMS};counts", 200, -0.1, 0.1}, "H.gtr.th"); - auto hHthTracking = dHMSGoodTrack.Histo1D( - {"H.gtr.th.Tracking", "Cuts: Tracking;#theta_{HMS};counts", 200, -0.1, 0.1}, "H.gtr.th"); - auto hHthPID = dHMSEl.Histo1D( - {"H.gtr.th.PID", "Cuts: Tracking+PID;#theta_{HMS};counts", 200, -0.1, 0.1}, "H.gtr.th"); - auto hHthTiming = dHMSElInTime.Histo1D( - {"H.gtr.th.Timing", "Cuts: Tracking+PID+Timing;#theta_{HMS};counts", 200, -0.1, 0.1}, - "H.gtr.th"); - // H.gtr.ph - auto hHphNoCuts = - d_coin.Histo1D({"H.gtr.ph.NoCuts", "No Cuts;#phi_{HMS};counts", 200, -0.1, 0.1}, "H.gtr.ph"); - auto hHphTracking = dHMSGoodTrack.Histo1D( - {"H.gtr.ph.Tracking", "Cuts: Tracking;#phi_{HMS};counts", 200, -0.1, 0.1}, "H.gtr.ph"); - auto hHphPID = dHMSEl.Histo1D( - {"H.gtr.ph.PID", "Cuts: Tracking+PID;#phi_{HMS};counts", 200, -0.1, 0.1}, "H.gtr.ph"); - auto hHphTiming = dHMSElInTime.Histo1D( - {"H.gtr.ph.Timing", "Cuts: Tracking+PID+Timing;#phi_{HMS};counts", 200, -0.1, 0.1}, - "H.gtr.ph"); - // H.gtr.y - auto hHyNoCuts = - d_coin.Histo1D({"H.gtr.y.NoCuts", "No Cuts;ytar;counts", 200, -10., 10.}, "H.gtr.y"); - auto hHyTracking = dHMSGoodTrack.Histo1D( - {"H.gtr.y.Tracking", "Cuts: Tracking;ytar;counts", 200, -10., 10.}, "H.gtr.y"); - auto hHyPID = - dHMSEl.Histo1D({"H.gtr.y.PID", "Cuts: Tracking+PID;ytar;counts", 200, -10., 10.}, "H.gtr.y"); - auto hHyTiming = dHMSElInTime.Histo1D( - {"H.gtr.y.Timing", "Cuts: Tracking+PID+Timing;ytar;counts", 200, -10., 10.}, "H.gtr.y"); - - // scalers - //auto total_charge = d_sh.Max("P.BCM4B.scalerChargeCut"); - //auto shms_el_real_scaler = d_sh.Max("P.pEL_REAL.scaler"); - //auto hms_el_real_scaler = d_sh.Max("P.hEL_REAL.scaler"); - //auto time_1MHz = d_sh.Max("P.1MHz.scalerTime"); - //auto time_1MHz_cut = d_sh.Max("P.1MHz.scalerTimeCut"); - - auto yield_all = d.Count(); - // 5 timing cut widths worth of random backgrounds - auto yield_coin = d_coin.Count(); - auto yield_HMSGoodTrack = dHMSGoodTrack.Count(); - auto yield_SHMSGoodTrack = dSHMSGoodTrack.Count(); - auto yield_COINGoodTrack = dCOINGoodTrack.Count(); - auto yield_HMSEl = dHMSEl.Count(); - auto yield_SHMSEl = dSHMSEl.Count(); - auto yield_COINEl = dCOINEl.Count(); - auto yield_HMSElInTime = dHMSElInTime.Count(); - auto yield_HMSElRandom = dHMSElRandom.Count(); - auto yield_SHMSElInTime = dSHMSElInTime.Count(); - auto yield_SHMSElRandom = dSHMSElRandom.Count(); - auto yield_COINElInTime = dCOINElInTime.Count(); - auto yield_COINElRandom = dCOINElRandom.Count(); - auto yield_coin_raw = dCOINElInTime.Count(); - auto yield_coin_random = dCOINElRandom.Count(); - - - // ------------------------------------- - // End lazy eval - // ------------------------------------- - auto n_coin_good = *yield_coin_raw - *yield_coin_random / 5.; - auto n_HMSElGood = *yield_HMSElInTime - *yield_HMSElRandom / 5; - auto n_SHMSElGood = *yield_SHMSElInTime - *yield_SHMSElRandom / 5; - auto n_COINElGood = *yield_COINElInTime - *yield_COINElRandom / 5; - - hPdpNoCuts->DrawCopy(); - //std::cout << " coin COUNTS : " << *(d_coin.Count()) << "\n"; - //std::cout << " yield_HMSEl : " << *(yield_HMSEl) << "\n"; - std::cout << " yield_COINEl : " << *(yield_COINEl) << "\n"; - //std::cout << " ALL COUNTS : " << *yield_all << "\n"; - //std::cout << " GOOD COUNTS : " << n_COINElGood << "\n"; - // - if( 4 != (*(yield_COINEl)) ){ - std::exit(-1); - } - std::exit(0); -} diff --git a/tests/elastic_test.sh b/tests/elastic_test.sh deleted file mode 100644 index 5d137e59c5413ab3ab02a67612ca8466182b04f9..0000000000000000000000000000000000000000 --- a/tests/elastic_test.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -#echo "This is the elastic testing..." -#echo " " -#echo "There are currently 0 tests to run!" -#which hcana -# -#ls -lrth -#ls -lrth build -# -#git clone git@eicweb.phy.anl.gov:jlab/hallc/exp/CSV/hallc_replay_csv.git -#git clone git@eicweb.phy.anl.gov:jlab/hallc/exp/CSV/online_csv.git -#cd online_csv -#ln -s ../hallc_reaply_csv/PARAM -## and the reset -# -#mkdir raw -#pushd raw -# wget coin.dat -#popd - - -singularity help build/Singularity.hcana.simg - - -singularity exec build/Singularity.hcana.simg hcana tests/elastic_test.cxx diff --git a/tests/elastic_test2.sh b/tests/elastic_test2.sh deleted file mode 100644 index 36da2058d88749b20c9af12ce265f23befd157c2..0000000000000000000000000000000000000000 --- a/tests/elastic_test2.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -echo "This is the elastic testing..." -echo " " -echo "There are currently 0 tests to run!" -which hcana - -ls -lrth -ls -lrth build - -git clone git@eicweb.phy.anl.gov:jlab/hallc/exp/CSV/hallc_replay_csv.git -git clone git@eicweb.phy.anl.gov:jlab/hallc/exp/CSV/online_csv.git - -cd online_csv -ln -s ../hallc_reaply_csv/PARAM -# and the reset - -mkdir raw -pushd raw - wget coin.dat -popd - - -singularity help build/Singularity.hcana.simg - -singularity exec build/Singularity.hcana.simg which hcana - -singularity exec build/Singularity.hcana.simg hcana tests/my_root_script.cxx - -echo " WOOOO" diff --git a/tests/my_root_script.cxx b/tests/my_root_script.cxx deleted file mode 100644 index 0d3686284d799790b779b7724cdbca81d3a5c129..0000000000000000000000000000000000000000 --- a/tests/my_root_script.cxx +++ /dev/null @@ -1,20 +0,0 @@ -void my_root_script() { - - - - std::cout << "Hello from my_root_script.cxx!\n"; - - std::cout << "This should be run with singularity\n"; - double pi = 3.14; - - auto pi_equals_3 = (3 == pi); - std::cout << " pi_equals_3 = " << pi_equals_3 << "\n"; - - if( pi_equals_3) { - std::cout << "what the hell?\n"; - std::exit( 0 ); - } - /* else */ - - std::exit( -1 ); -} diff --git a/tests/replay_elastic_data.sh b/tests/replay_elastic_data.sh deleted file mode 100644 index 48b147f737be5ce6b44ed32e39f3505b377dccb8..0000000000000000000000000000000000000000 --- a/tests/replay_elastic_data.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -echo "This is the elastic testing..." -echo " " -echo "There are currently 0 tests to run!" -which hcana - -ls -lrth -ls -lrth build -mkdir -p ROOTfiles -git clone https://eicweb.phy.anl.gov/whit/ci_test_data.git -git clone https://eicweb.phy.anl.gov/jlab/hallc/exp/CSV/hallc_replay_csv.git -git clone https://eicweb.phy.anl.gov/jlab/hallc/exp/CSV/online_csv.git - -cd online_csv -mkdir -p logs -ln -s ../hallc_replay_csv/PARAM -ln -s ../hallc_replay_csv/DBASE -ln -s ../hallc_replay_csv/CALIBRATION -ln -s ../hallc_replay_csv/DEF-files -ln -s ../hallc_replay_csv/MAPS -ln -s ../hallc_replay_csv/SCRIPTS -ln -s ../hallc_replay_csv/DATFILES -ln -s ../ci_test_data/raw -ln -s ../ROOTfiles -# and the reset - -ls -lrth -ls -lrth raw/ -ls -lrth ROOTfiles/ -pwd -# run replay script -df -h - -singularity exec ../build/Singularity.hcana.simg hcana -b -q "../tests/elastic_coin_replay.cxx+(6012,50000)" - -echo "hcana calls... the coin replay script and outputs blah.root" -