Skip to content

Commit

Permalink
Merge branch 'development' into iss373-bgMergeTwice
Browse files Browse the repository at this point in the history
  • Loading branch information
raffaelladevita committed Dec 16, 2024
2 parents e3548d9 + 8a16989 commit a67c7e1
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 68 deletions.
107 changes: 107 additions & 0 deletions bin/hipo-multi-merge
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env ruby

require 'optparse'
require 'ostruct'
require 'fileutils'

def print_log(name, val)
puts name.rjust(30) + " = #{val}"
end

# user options
@args = OpenStruct.new
@args.inputs = nil
@args.output_dir = nil
@args.prefix = nil
@args.num_merge = nil
@args.use_batch = false
@args.dry_run = false
OptionParser.new do |o|
o.banner = '''
This tool merges a set of input HIPO files to a set of output HIPO files,
where you may control the number of input files per output file; for example,
use this tool if you have 1000 small HIPO files but would rather have 10
large HIPO files.
'''
o.separator "USAGE: #{$0} [OPTIONS]..."
o.separator ''
o.separator 'REQUIRED OPTIONS:'
o.on('-i', '--input INPUTS', 'input directory or file glob;', 'surround file glob in quotes') { |a| @args.inputs = a }
o.on('-o', '--output OUTPUT_DIR', 'output directory') { |a| @args.output_dir = a }
o.on('-p', '--prefix OUTPUT_PREFIX', 'output filename prefix; names will be:', ' [OUTPUT_DIR]/[OUTPUT_PREFIX]_#####.hipo') { |a| @args.prefix = a }
o.on('-n', '--num NUM_FILES', 'number of files per output merged file') { |a| @args.num_merge = a.to_i }
o.separator ''
o.separator 'OPTIONAL OPTIONS:'
o.on('-b', '--batch', 'submit jobs to Slurm', '(default is sequential jobs)') { |a| @args.use_batch = true }
o.on('-d', '--dry-run', 'just print what would be done') { |a| @args.dry_run = true }
o.on_tail('-h', '--help', 'show this message') do
puts o
exit
end
end.parse! ARGV.empty? ? ['--help'] : ARGV

# check required options
if [@args.inputs, @args.output_dir, @args.prefix, @args.num_merge].include? nil
raise 'missing required option(s;) re-run with "--help" for guidance.'
end
raise 'option "--num" must be greater than zero' unless @args.num_merge > 0

# glob inputs
input_glob = File.expand_path @args.inputs
input_glob = File.join input_glob, "*.hipo" if File.directory? input_glob
print_log 'input glob', input_glob
print_log 'output dir', @args.output_dir
print_log 'output prefix', @args.prefix
print_log 'num files per output', @args.num_merge

# chunks
input_files = Dir.glob input_glob
raise "no input files found with glob '#{input_glob}'" if input_files.empty?
input_chunks = input_files.each_slice(@args.num_merge).to_a
print_log 'num input files', input_files.size
print_log 'num output files', input_chunks.size
raise 'option "--num" >= num input files, therefore there is nothing to do' if input_chunks.size == 1

# build commands
puts "="*82
merge_cmds = input_chunks.each_with_index.map do |input_chunk, chunk_num|
out_name = File.join @args.output_dir, "#{@args.prefix}_#{chunk_num.to_s.rjust(5, '0')}.hipo"
raise "output file #{out_name} already exists; cannot overwrite! delete it or choose another path/name" if File.exist? out_name
[ 'hipo-utils', '-merge', '-o', out_name, *input_chunk ].join ' '
end

# sbatch commands
if @args.use_batch
sbatch_args = {
'job-name' => "hipo_multi_merge___#{@args.prefix}",
'account' => 'clas12',
'partition' => 'production',
'mem-per-cpu' => 500,
'time' => '1:00:00',
'ntasks' => 1,
'cpus-per-task' => 1,
}.map{ |opt, val| "--#{opt}=#{val.to_s}" }
exe_cmds = merge_cmds.each_with_index.map do |merge_cmd, job_num|
log_name = "/farm_out/%u/%x_#{job_num.to_s.rjust(5, '0')}"
[
'sbatch',
*sbatch_args,
"--output=#{log_name}.out",
"--error=#{log_name}.err",
"--wrap='#{merge_cmd}'",
].join ' '
end
else
exe_cmds = merge_cmds
end

# execute
if @args.dry_run
puts 'THIS IS JUST A DRY RUN. Here are the commands which would be executed:'
puts "="*82
puts "mkdir -p #{@args.output_dir}"
exe_cmds.each do |cmd| puts cmd end
else
FileUtils.mkdir_p @args.output_dir
exe_cmds.each do |cmd| system cmd end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,37 @@
//package clas12vis;

package org.jlab.geom.detector.alert.ATOF;

import org.jlab.geom.base.ConstantProvider;
import org.jlab.geom.base.DetectorTransformation;
import org.jlab.geom.base.Factory;
import org.jlab.geom.component.ScintillatorPaddle;
import org.jlab.geom.prim.Plane3D;
import org.jlab.geom.prim.Point3D;
import org.jlab.geom.prim.Transformation3D;

import java.util.ArrayList;
import java.util.List;

/**
* @author viktoriya
* this is the latest ATOF geometry class to be used in reco. and in GEMC simulations!
* commit on July 02, 2020
* @author viktoriya, pilleux
* Original geometry July 02, 2020
* Updated December 2024 to match actual atof conventions
* ATOF geometry class to be used in reco. and in GEMC simulations!
*/
public class AlertTOFFactory implements Factory<AlertTOFDetector, AlertTOFSector, AlertTOFSuperlayer, AlertTOFLayer> {

private final int nsectors = 15;
private final int nsuperl = 2;
private final int nlayers1 = 10;
private final int npaddles = 4;

//Convention definitions: https://clasweb.jlab.org/wiki/index.php/File:Atof_def.png
//The atof has 15 phi sectors.
private final int nsectors = 15;
//Top superlayer (index 1) = wedges.
//Bottom one (0) = bar.
private final int nsuperl = 2;
//Layers = quarters of sectors.
private final int nlayers = 4;
//Components = slices in z. 10 for the wedges, 1 for the bar.
private final int ncomponents = 10;

//Each pad = quarter of module
private final double openAng_pad_deg = 6.0;
private final double openAng_pad_rad = Math.toRadians(openAng_pad_deg);
private final double openAng_sector_rad = npaddles * openAng_pad_rad;
//4 pads = 4 layers = 1 sector
private final double openAng_sector_deg = nlayers * openAng_pad_deg;

@Override
public AlertTOFDetector createDetectorCLAS(ConstantProvider cp) {
Expand Down Expand Up @@ -72,23 +76,15 @@ public AlertTOFSuperlayer createSuperlayer(ConstantProvider cp, int sectorId, in
if (!(0 <= sectorId && sectorId < nsectors)) throw new IllegalArgumentException("Error: invalid sector=" + sectorId);
if (!(0 <= superlayerId && superlayerId < nsuperl)) throw new IllegalArgumentException("Error: invalid superlayer=" + superlayerId);
AlertTOFSuperlayer superlayer = new AlertTOFSuperlayer(sectorId, superlayerId);

if (superlayerId == 0) {
int nlayers0 = 1;
for (int layerId = 0; layerId < nlayers0; layerId++)
superlayer.addLayer(createLayer(cp, sectorId, superlayerId, layerId));
} else {
for (int layerId = 0; layerId < nlayers1; layerId++)
superlayer.addLayer(createLayer(cp, sectorId, superlayerId, layerId));
}
for (int layerId = 0; layerId < nlayers; layerId++) superlayer.addLayer(createLayer(cp, sectorId, superlayerId, layerId));
return superlayer;
}

@Override
public AlertTOFLayer createLayer(ConstantProvider cp, int sectorId, int superlayerId, int layerId) {
if (!(0 <= sectorId && sectorId < nsectors)) throw new IllegalArgumentException("Error: invalid sector=" + sectorId);
if (!(0 <= superlayerId && superlayerId < nsuperl)) throw new IllegalArgumentException("Error: invalid superlayer=" + superlayerId);
if (!(0 <= layerId && layerId < nlayers1)) throw new IllegalArgumentException("Error: invalid layer=" + layerId);
if (!(0 <= layerId && layerId < nlayers)) throw new IllegalArgumentException("Error: invalid layer=" + layerId);

double R0 = 77.0d;
double R1 = 80.0d;
Expand All @@ -109,54 +105,68 @@ public AlertTOFLayer createLayer(ConstantProvider cp, int sectorId, int superlay
double gap_pad_z = 0.3d; // mm, gap between paddles in z

AlertTOFLayer layer = new AlertTOFLayer(sectorId, superlayerId, layerId);

List<Plane3D> planes = new ArrayList<>();

double len_b = layerId * pad_z + layerId * gap_pad_z; // back paddle plan
double len_f = len_b + pad_z; // front paddle plan

//Dimensions for the bar
double Rl = R0;
double dR = dR0;
double widthTl = small_pad_b2;
double widthBl = small_pad_b1;

//Dimensions for the wedge
if (superlayerId == 1) {
Rl = R1;
dR = dR1;
widthTl = pad_b2;
widthBl = pad_b1;
}

for (int padId = 0; padId < npaddles; padId++) {
Point3D p0 = new Point3D(-dR / 2, -widthBl / 2, len_f);
Point3D p1 = new Point3D(dR / 2, -widthTl / 2, len_f);
Point3D p2 = new Point3D(dR / 2, widthTl / 2, len_f);
Point3D p3 = new Point3D(-dR / 2, widthBl / 2, len_f);

Point3D p4 = new Point3D(-dR / 2, -widthBl / 2, len_b);
Point3D p5 = new Point3D(dR / 2, -widthTl / 2, len_b);
Point3D p6 = new Point3D(dR / 2, widthTl / 2, len_b);
Point3D p7 = new Point3D(-dR / 2, widthBl / 2, len_b);
ScintillatorPaddle Paddle = new ScintillatorPaddle(sectorId * 4 + padId, p0, p1, p2, p3, p4, p5, p6, p7);

double openAng_sector_deg = npaddles * openAng_pad_deg;
Paddle.rotateZ(Math.toRadians(padId * openAng_pad_deg + sectorId * openAng_sector_deg));

double xoffset;
double yoffset;

xoffset = (Rl + dR / 2) * Math.cos(padId * openAng_pad_rad + sectorId * openAng_sector_rad);
yoffset = (Rl + dR / 2) * Math.sin(padId * openAng_pad_rad + sectorId * openAng_sector_rad);

Paddle.translateXYZ(xoffset, yoffset, 0);

// Add the paddles to the list
layer.addComponent(Paddle);

//Layer = quarter of a sector
double current_angle_deg = layerId * openAng_pad_deg + sectorId * openAng_sector_deg;
//Aligning the y axis with the separation between modules 0 and 14
current_angle_deg = current_angle_deg + 90 + 3;

//Component = z slice.
//There are 10 for the wedge/top/sl=1
int current_ncomponents = ncomponents;
//There is only one for the bar/bottom/sl=0
if(superlayerId==0) current_ncomponents = 1;

//Starting loop on components
for (int padId = 0; padId < current_ncomponents; padId++) {

//Component index increases with increasing z
double len_b = padId * pad_z + padId * gap_pad_z; // back paddle plan
double len_f = len_b + pad_z; // front paddle plan

Point3D p0 = new Point3D(-dR / 2, -widthBl / 2, len_f);
Point3D p1 = new Point3D(dR / 2, -widthTl / 2, len_f);
Point3D p2 = new Point3D(dR / 2, widthTl / 2, len_f);
Point3D p3 = new Point3D(-dR / 2, widthBl / 2, len_f);

Point3D p4 = new Point3D(-dR / 2, -widthBl / 2, len_b);
Point3D p5 = new Point3D(dR / 2, -widthTl / 2, len_b);
Point3D p6 = new Point3D(dR / 2, widthTl / 2, len_b);
Point3D p7 = new Point3D(-dR / 2, widthBl / 2, len_b);

//Component index is the z slice for the top/wedge/sl=1
int component = padId;
//It is 10 for the bottom/bar/sl=0
if(superlayerId==0) component = 10;

ScintillatorPaddle Paddle = new ScintillatorPaddle(component, p0, p1, p2, p3, p4, p5, p6, p7);

Paddle.rotateZ(Math.toRadians(current_angle_deg));

double xoffset;
double yoffset;

xoffset = (Rl + dR / 2) * Math.cos(Math.toRadians(current_angle_deg));
yoffset = (Rl + dR / 2) * Math.sin(Math.toRadians(current_angle_deg));

Paddle.translateXYZ(xoffset, yoffset, 0);

// Add the paddles to the list
layer.addComponent(Paddle);
}

Plane3D plane = new Plane3D(0, Rl, 0, 0, 1, 0);
plane.rotateZ(sectorId * openAng_sector_rad - Math.toRadians(90));
planes.add(plane);

return layer;
}

Expand Down
2 changes: 1 addition & 1 deletion common-tools/cnuphys/parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.8.6.5</version>
<version>4.8.6.6</version>
<configuration>
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
</configuration>
Expand Down
4 changes: 2 additions & 2 deletions parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.8.6.5</version>
<version>4.8.6.6</version>
<configuration>
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
</configuration>
Expand All @@ -71,7 +71,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.1</version>
<version>3.11.2</version>
<configuration>
<doctitle>coatjavadocs</doctitle>
<windowtitle>coatjavadocs</windowtitle>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ public void processEvent(DataEvent event) {

// Place all of the hits into clusters
List<HTCCCluster> clusters = new ArrayList();
HTCCCluster cluster;
while (!remainingHits.isEmpty() && (cluster = findCluster(remainingHits)) != null) {
clusters.add(cluster);
while (!remainingHits.isEmpty()) {
HTCCCluster cluster = findCluster(remainingHits);
if(cluster!=null) clusters.add(cluster);
}

// Push all of the clusters into the bank and print the results
Expand Down

0 comments on commit a67c7e1

Please sign in to comment.