Compare commits

...

268 Commits

Author SHA1 Message Date
Vignesh Sitaraman 8806af3f6d modified: TrackRecon.C
modified:   anasen_fem/wires2d.sif
	modified:   run_tr.sh
2026-09-25 23:05:24 -04:00
Vignesh Sitaraman 01783858fa modified: Armory/ClassPW.h
modified:   Armory/PCZRecon.h
	modified:   TrackRecon.C
2026-09-24 11:39:50 -04:00
Vignesh Sitaraman 018a92f647 modified: TrackRecon.C proton beam energy correction
modified:   anasen_fem/run.py
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/scalars_weight.dat.names
2026-09-23 15:17:49 -04:00
Vignesh Sitaraman 3edbfa5bd8 modified: anasen_fem/README.md added the Shockley-Ramo dot calculation capability adapted fom Sudarsan's branch with a new visusalisation scheme to show the +ve and-ve sides on a logscale
modified:   anasen_fem/clean.sh
	new file:   anasen_fem/dotproduct.py
	new file:   anasen_fem/paraview_dotproduct.py
	modified:   anasen_fem/paraview_plotter.py
	modified:   anasen_fem/run.py
	modified:   anasen_fem/scalars.dat.names
	new file:   anasen_fem/scalars_weight.dat
	new file:   anasen_fem/scalars_weight.dat.names
	modified:   anasen_fem/wires2d.sif
	new file:   anasen_fem/wires2d_weight.sif
	modified:   anasen_fem/wires_gmsh2d_bc.py
2026-09-23 12:14:05 -04:00
Vignesh Sitaraman aebb9854ec modified: TrackRecon.C corrected a1c1 factors and diagnostics 2026-09-21 18:11:38 -04:00
Vignesh Sitaraman 19262299ba modified: run_27Al.sh
modified:   run_tr.sh
2026-09-18 17:48:37 -04:00
Vignesh Sitaraman f30e244d27 modified: TrackRecon.C the code was NOT dead 2026-09-18 17:48:06 -04:00
Vignesh Sitaraman 397c410320 Revert " modified: TrackRecon.C removed some dead code, changed cfrac parameters for 27Al and 17F"
This reverts commit cc32682de3.
2026-09-18 17:27:27 -04:00
Vignesh Sitaraman cc32682de3 modified: TrackRecon.C removed some dead code, changed cfrac parameters for 27Al and 17F 2026-09-18 16:57:54 -04:00
Vignesh Sitaraman 7ec86569fb modified: TrackRecon.C aded a2c1 and a2c2 toplogies just to see waht tehy look like
modified:   run_27Al.sh
	modified:   run_tr.sh
	new file:   scratch/RunwiseTrend.C diagnostics to see variationwith run
	modified:   slope_intercept_results_17F.dat
2026-09-14 11:00:08 -04:00
Vignesh Sitaraman bbf00ad3c6 modified: TrackRecon.C added 2.23 gated ex_vs_something spectra as a diagnostic for the 27Al run 2026-09-13 13:05:35 -04:00
Vignesh Sitaraman 7be00bcb3f modified: TrackRecon.C added qqq xy diagnostics for beam 2026-09-10 14:45:55 -04:00
Vignesh Sitaraman d46f456fd9 modified: TrackRecon.C
modified:   eloss_calculations/Eloss.py
	modified:   eloss_calculations/alpha_lookup_50MeV_250torr_4pc.dat redone at 0.89
	modified:   eloss_calculations/aluminum_lookup_80MeV_250torr_4pc.dat
	modified:   eloss_calculations/deutron_lookup_30MeV_250torr_4pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_250torr_4pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_250torr_4pc.dat
	modified:   eloss_calculations/proton_lookup_30MeV_250torr_4pc.dat
	modified:   run_17F.sh
	modified:   run_27Al.sh
2026-09-10 10:47:51 -04:00
Vignesh Sitaraman 97357e383e modified: TrackRecon.C 2026-09-10 08:19:16 -04:00
Vignesh Sitaraman 83114262db modified: TrackRecon.C 2026-09-09 10:49:17 -04:00
Vignesh Sitaraman 9b2c20daca modified: TrackRecon.C
modified:   scratch/make_prettyplots.C
2026-09-08 15:35:43 -04:00
Vignesh Sitaraman 38c8c7e0e0 modified: TrackRecon.C put in timing gates and phi gates uniformly
modified:   .gitignore
	deleted:    Analysis.C
	deleted:    Analyzer.C deleted the older analysis formats
	deleted:    Analyzer.h
	deleted:    Timing_Summary_Matplotlib.png
	deleted:    WedgeChVAnode.jpeg
	modified:   run_tr.sh
	modified:   scratch/make_prettyplots.C added rebinning capability and log z scale option
2026-09-08 14:37:04 -04:00
Vignesh Sitaraman ec43a81030 modified: TrackRecon.C implemented and applied beamtilt parameter calcualtion and application
modified:   run_27Al.sh
	new file:   scratch/FitBeamAxis.C code to figure out beamtilt
2026-09-07 09:57:13 -04:00
Vignesh Sitaraman 7f936f6a53 modified: run_27Al.sh testing beamtilt theory 2026-09-06 16:05:13 -04:00
Vignesh Sitaraman 048b11fce3 modified: .gitignore
new file:   CLAUDE.md
2026-09-06 13:41:38 -04:00
Vignesh Sitaraman d3c4c47e41 modified: TrackRecon.C
modified:   run_tr.sh
2026-09-06 10:43:55 -04:00
Vignesh Sitaraman fde75b8a77 modified: TrackRecon.C
modified:   run_27Al.sh
2026-09-04 14:44:10 -04:00
Vignesh Sitaraman 80b079b81d deleted: Armory/mass20.txt
modified:   TrackRecon.C paap gating
	modified:   run_17F.sh
	modified:   run_27Al.sh
	modified:   run_tr.sh
	modified:   scratch/overlay_2d.C
2026-09-04 10:16:34 -04:00
Vignesh Sitaraman 78add5432a modified: TrackRecon.C added plots for dE_cal vs dT and Ex vs dT
modified:   eloss_calculations/alpha_lookup_50MeV_250torr_3pc.dat for 0.89 dedx
	modified:   eloss_calculations/aluminum_lookup_80MeV_250torr_3pc.dat
	modified:   eloss_calculations/deutron_lookup_30MeV_250torr_3pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/proton_lookup_30MeV_250torr_3pc.dat
	modified:   run_27Al.sh collapsed the parallelization a bit
	modified:   scratch/overlay_2d.C added minz, rebinning and box option
2026-09-02 13:29:16 -04:00
Vignesh Sitaraman ffb1c1a960 modified: TrackRecon.C
modified:   scratch/overlay_2d.C
2026-09-02 09:44:36 -04:00
Vignesh Sitaraman 4d9145d532 modified: TrackRecon.C mismatched braces 2026-09-02 09:31:54 -04:00
Vignesh Sitaraman fce1fb6c1d modified: TrackRecon. 2026-09-02 09:24:56 -04:00
Vignesh Sitaraman bf8d4089f1 modified: TrackRecon.C
modified:   run_17F.sh
2026-09-02 08:39:47 -04:00
Vignesh Sitaraman 941f450af1 modified: TrackRecon.C
modified:   scratch/overlay_2d.C
2026-09-01 14:05:46 -04:00
Vignesh Sitaraman 461d60a50c modified: eloss_calculations/Eloss.py trying out with 0.89/0.9 multiplier on all particles
modified:   eloss_calculations/alpha_lookup_50MeV_250torr_3pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_250torr_3pc.dat
	modified:   eloss_calculations/deutron_lookup_30MeV_250torr_3pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/proton_lookup_30MeV_250torr_3pc.dat
	new file:   scratch/overlay_2d.C small script to overlay multiple 2d histograms from the same file
    various scripts used to optimise the different parameters in the analysis
	new file:   scratch/CompareElasticLocus.C
	new file:   scratch/PlotDedxScan.C
	new file:   scratch/RunMultiFit.C
	new file:   scratch/ScanDedxScale.C
2026-09-01 11:43:28 -04:00
Vignesh Sitaraman d245fc2679 modified: TrackRecon.C fixed typo 2026-09-01 06:41:04 -04:00
Vignesh Sitaraman dd6b938eb2 new file: MiscEdE.C plotting the radioactive beam IC PID as well as looking for timing coincideences between that and the MCP-Rf time
new file:   run_misc_ede.sh same as above
	modified:   TrackRecon.C added beamE gated plots for the step aladder for 27Al
	modified:   run_17F.sh doing more files now
	modified:   run_27Al.sh scaling change to 0.9 to try it out
	modified:   run_tr.sh
	modified:   scratch/make_prettyplots.C add log scale option to the 2D plots
2026-09-01 06:24:36 -04:00
Vignesh Sitaraman 3dd678221a modified: TrackRecon.C implementation of Ex vs TOF plot not working rn 2026-08-31 14:58:29 -04:00
Vignesh Sitaraman b5e88a6731 modified: TrackRecon.C minor changes 2026-08-31 14:36:54 -04:00
Vignesh Sitaraman d211971904 modified: TrackRecon.C added topology gated spectra as well as calibrated versions of the a2 ratio plots 2026-08-31 09:40:14 -04:00
Vignesh Sitaraman 6619613db5 modified: TrackRecon.C restructuring the p(a,a)p branch to make it more readable need to implement per topo version of plots
modified:   run_27Al.sh
	modified:   run_tr.sh
2026-08-30 14:29:45 -04:00
Vignesh Sitaraman e83775d79f modified: TrackRecon.C added some plots, perppeing for more major changes to the proton branch
modified:   run_17F.sh
	modified:   run_27Al.sh
2026-08-27 10:29:24 -04:00
Vignesh Sitaraman 8cd98c35e1 modified: .gitignore added Ryan's autofit routine to gitignore 2026-08-26 12:11:58 -04:00
Vignesh Sitaraman 3e60105617 modified: TrackRecon.C remoevd the gated proton spectra dn introduced new histos where we "snap" to different exicited state and plto the Ekin_vs_Etrack
modified:   run_27Al.sh dEdx scaling scan
2026-08-21 13:45:18 -04:00
Vignesh Sitaraman c0c49be0c9 modified: TrackRecon.C consolidated the ditehr sigma, the timing cuts and reset the beam xy to (0,0), beamenergy gets set to 0.001 instead of returning for values that are beyond calculated catima range.
Moved some diagnostic plots because they were out of range for the boleans to actually catch them, lifted the si time ditehring so that it gets applied everywhere for smootehr time plots.
	modified:   eloss_calculations/Eloss.py introduced a external scaling factr to allow eloss calculations to be paired with the run scripts to figure out the right dEdx scaling
	modified:   run_27Al.sh
2026-08-18 15:14:18 -04:00
Vignesh Sitaraman 9416638af6 modified: TrackRecon.C changed the vertex by wire to be calibrated dE 2026-08-17 13:53:26 -04:00
Vignesh Sitaraman 0a7dd1bcf6 modified: TrackRecon.C gate changes 2026-08-17 11:37:21 -04:00
Vignesh Sitaraman cf584a6d7a modified: Armory/PCZRecon.h added a2c0
modified:   TrackRecon.C added a2c0, changed a1c1 cfrac parameters based on optimisation for the alpha and source data. Might need to be changed for the reaction though dfo rsome reason the apramteres don't quite makes sense
	modified:   eloss_calculations/Eloss.py added a scaling factor to particles with A>10 based to make the beams go further into the detector based on reaction data
	modified:   pc_energy_calibration.dat halved the anode dE cal to account for the misamtch between calib and rpedict for the source data
2026-08-17 11:05:22 -04:00
Vignesh Sitaraman c83557f30c modified: Armory/PCZRecon.h changed from vertex xy checks which al;way s defaulted to the same version to a proximity check to the wire ( using pitchok)
modified:   TrackRecon.C added diagnostic plots for recon and eloss
2026-08-14 14:22:08 -04:00
Vignesh Sitaraman ed505139b4 modified: pc_energy_calibration.dat corrected calibs for 16 18 20 and 23 2026-08-13 20:54:42 -04:00
Vignesh Sitaraman 9b68c5b720 modified: TrackRecon.C added some more diagnostics plots for the reaciton dataset 2026-08-13 11:11:29 -04:00
Vignesh Sitaraman 98c48af0b1 new file: Armory/PCZRecon.h refactor to lift a1c0 and a1c1 frac into a class PCZRecon which includes the a1c2 slope correction as well. Making the code more readable and easier to maintain.
also changes the model_invert into a function call instead of using the TF1 class
	modified:   TrackRecon.C refactor plus removal of older vesions of pcz and track reconstruction from the old analysis. Changed the ranges for dECalib spectra since their max was way too high.
	modified:   pc_energy_calibration.dat changed the calibration of anode 2-4 to the same as anode1 and 5 to 6 becuase they were causing bifuraction in signal. This might have been happening because the 17F data is poisoning the calibraion. This hypothesis
    is pending validation however.
2026-08-12 15:02:35 -04:00
Vignesh Sitaraman fbd601ec40 modified: run_27Al.sh 2026-08-12 10:30:15 -04:00
Vignesh Sitaraman 21fd1ca4d2 modified: TrackRecon.C correction of cathode multiplicity gate on teh pc events 2026-08-12 10:30:15 -04:00
Vignesh Sitaraman 542e927049 modified: TrackRecon.C correction of cathode multiplicity gate on teh pc events 2026-08-11 14:43:38 -04:00
Vignesh Sitaraman 2784671732 modified: TrackRecon.C PID gate on the suspected proton locus and prudcing the Ex function corresponding to the state. Also implemented a1c0 dithering for the reaction data 2026-08-11 14:19:29 -04:00
Vignesh Sitaraman 774050dfdf modified: TrackRecon.C 2026-08-11 12:58:36 -04:00
Vignesh Sitaraman caeff0d7c5 modified: TrackRecon.C rehaul of the calibration dynamic so that any channels that dont have sufficient sx3 a1c2 stats get calibrated by lining up their centroids with those that do. Still a bit iffy on the bad anode formalism but keeping it in for now.
modified:   pc_energy_calibration.dat
	modified:   pccal/fit_pc_energy_calibration.C
2026-08-10 14:27:52 -04:00
Vignesh Sitaraman 6ff00bedc2 modified: pc_energy_calibration.dat
modified:   run_27Al.sh
2026-08-08 15:00:51 -04:00
Vignesh Sitaraman 8e9d539653 modified: TrackRecon.C 2026-08-08 14:59:52 -04:00
Vignesh Sitaraman 902afaad54 pcgain 2026-08-07 11:02:49 -04:00
Vignesh Sitaraman 07e30a5ddd modified: TrackRecon.C implemented new energy calibration paradigm for the PC and some other minor changes
modified:   pc_energy_calibration.dat
	modified:   pccal/fit_pc_energy_calibration.C
	modified:   run_27Al.sh
2026-08-06 17:04:17 -04:00
Vignesh Sitaraman 00c507e0ac modified: Armory/ClassPW.h
modified:   TrackRecon.C corrected anode cal logic with changes to classpw.h to incorporate the guardwire to cathode wire region for anode charge collection
	modified:   pc_energy_calibration.dat
2026-08-06 13:30:51 -04:00
Vignesh Sitaraman 2d3bcc7c74 modified: TrackRecon.C calibration script in progress needs overhaul
modified:   run_27Al.sh
2026-08-06 10:19:41 -04:00
Vignesh Sitaraman 58d0ef1839 modified: TrackRecon.C changed the calibrationf for anode cathode so that we can get Eloss difference in the active area of the proportional counter. Using only ground staet now as opposed to snapping to the neareast Ex
modified:   run_27Al.sh
	modified:   run_tr.sh
2026-08-05 10:51:19 -04:00
Vignesh Sitaraman 51ece5e69b modified: TrackRecon.C corrected some eval calls and implemeneted a beam E inversion function to get the beam energy from the measured Ex and theta and compare it to the Beam E from Eloss
modified:   run_27Al.sh
2026-08-03 12:07:26 -04:00
Vignesh Sitaraman bd79dda26b modified: MakeVertex.C new version of sudarsan's code
modified:   TrackRecon.C changes to selectivity of detecrtor channels based on sudarsan's code and some changes to event structure
	modified:   run_27Al.sh
2026-08-03 09:45:43 -04:00
Vignesh Sitaraman 14999546b7 modified: Armory/HistPlotter.h
modified:   TrackRecon.C made changes to account for frequent crashes due to the number of histograms. New changes allow for flsuhing of data to histograms every n events
	modified:   run_27Al.sh
2026-07-31 14:05:18 -04:00
Vignesh Sitaraman a292695a4d modified: TrackRecon.C
modified:   run_27Al.sh
	modified:   run_tr.sh
2026-07-30 15:32:53 -04:00
Vignesh Sitaraman 173fb36ea2 modified: TrackRecon.C
modified:   run_27Al.sh
2026-07-29 14:44:53 -04:00
Vignesh Sitaraman 3e9c86d8dc modified: .gitignore
modified:   TrackRecon.C
	new file:   pc_energy_calibration.dat
	modified:   pccal/fit_pc_energy_calibration.C
	modified:   run_27Al.sh
	modified:   run_tr.sh
2026-07-28 11:32:30 -04:00
Vignesh Sitaraman 3b09639c60 modified: TrackRecon.C 2026-07-14 14:56:16 -04:00
Vignesh Sitaraman 2bd4f4eb33 modified: TrackRecon.C
new file:   pccal/fit_pc_energy_calibration.C
2026-07-14 13:45:26 -04:00
Vignesh Sitaraman a3cab973be modified: TrackRecon.C 2026-07-13 14:05:09 -04:00
Vignesh Sitaraman f17259c8cc modified: TrackRecon.C
modified:   run_tr.sh
2026-07-13 13:32:48 -04:00
Vignesh Sitaraman 95f15ed23d modified: TrackRecon.C
modified:   run_tr.sh
2026-07-12 08:52:20 -04:00
Vignesh Sitaraman aa960fd711 modified: eloss_calculations/Eloss.py
modified:   eloss_calculations/alpha_lookup_50MeV_250torr_3pc.dat
	modified:   eloss_calculations/alpha_lookup_50MeV_250torr_4pc.dat
	modified:   eloss_calculations/alpha_lookup_50MeV_350torr_3pc.dat
	modified:   eloss_calculations/alpha_lookup_50MeV_350torr_4pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_250torr_3pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_250torr_4pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_350torr_3pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_350torr_4pc.dat
	modified:   eloss_calculations/deutron_lookup_30MeV_250torr_3pc.dat
	modified:   eloss_calculations/deutron_lookup_30MeV_250torr_4pc.dat
	modified:   eloss_calculations/deutron_lookup_30MeV_350torr_3pc.dat
	modified:   eloss_calculations/deutron_lookup_30MeV_350torr_4pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_250torr_4pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_350torr_3pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_350torr_4pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_250torr_4pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_350torr_3pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_350torr_4pc.dat
	modified:   eloss_calculations/proton_lookup_30MeV_250torr_3pc.dat
	modified:   eloss_calculations/proton_lookup_30MeV_250torr_4pc.dat
	modified:   eloss_calculations/proton_lookup_30MeV_350torr_3pc.dat
	modified:   eloss_calculations/proton_lookup_30MeV_350torr_4pc.dat
2026-07-10 16:14:34 -04:00
Vignesh Sitaraman 356d0c65b2 modified: TrackRecon.C
modified:   run_tr.sh
2026-07-10 14:57:24 -04:00
Vignesh Sitaraman ba8e8440e8 modified: Armory/ClassPW.h
modified:   TrackRecon.C
	modified:   eloss_calculations/Eloss.py
	modified:   eloss_calculations/alpha_lookup_50MeV_250torr_3pc.dat
	modified:   eloss_calculations/alpha_lookup_50MeV_250torr_4pc.dat
	modified:   eloss_calculations/alpha_lookup_50MeV_350torr_3pc.dat
	modified:   eloss_calculations/alpha_lookup_50MeV_350torr_4pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_250torr_3pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_250torr_4pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_350torr_3pc.dat
	modified:   eloss_calculations/aluminum_lookup_80MeV_350torr_4pc.dat
	new file:   eloss_calculations/deutron_lookup_30MeV_250torr_3pc.dat
	new file:   eloss_calculations/deutron_lookup_30MeV_250torr_4pc.dat
	new file:   eloss_calculations/deutron_lookup_30MeV_350torr_3pc.dat
	new file:   eloss_calculations/deutron_lookup_30MeV_350torr_4pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_250torr_4pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_350torr_3pc.dat
	modified:   eloss_calculations/fluorine_lookup_70MeV_350torr_4pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_250torr_3pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_250torr_4pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_350torr_3pc.dat
	modified:   eloss_calculations/oxygen_lookup_70MeV_350torr_4pc.dat
	new file:   eloss_calculations/proton_lookup_30MeV_250torr_3pc.dat
	new file:   eloss_calculations/proton_lookup_30MeV_250torr_4pc.dat
	new file:   eloss_calculations/proton_lookup_30MeV_350torr_3pc.dat
	new file:   eloss_calculations/proton_lookup_30MeV_350torr_4pc.dat
	modified:   run_17F.sh
	modified:   run_27Al.sh
	modified:   run_tr.sh
2026-07-10 14:32:52 -04:00
Vignesh Sitaraman dae9ca32cc modified: MakeVertex.C
modified:   eloss_calculations/Eloss.py
	deleted:    eloss_calculations/alpha_lookup_20MeV_3pc.dat
	deleted:    eloss_calculations/alpha_lookup_20MeV_3pc_350Torr.dat
	deleted:    eloss_calculations/alpha_lookup_20MeV_4pc.dat
	deleted:    eloss_calculations/alpha_lookup_20MeV_4pc_350Torr.dat
	renamed:    eloss_calculations/deutron_lookup_20MeV_3pc.dat -> eloss_calculations/alpha_lookup_50MeV_250torr_3pc.dat
	new file:   eloss_calculations/alpha_lookup_50MeV_250torr_4pc.dat
	new file:   eloss_calculations/alpha_lookup_50MeV_350torr_3pc.dat
	new file:   eloss_calculations/alpha_lookup_50MeV_350torr_4pc.dat
	deleted:    eloss_calculations/alpha_lookup_6.0MeV.dat
	new file:   eloss_calculations/aluminum_lookup_80MeV_250torr_3pc.dat
	renamed:    eloss_calculations/aluminum_lookup_80MeV_4pc.dat -> eloss_calculations/aluminum_lookup_80MeV_250torr_4pc.dat
	new file:   eloss_calculations/aluminum_lookup_80MeV_350torr_3pc.dat
	renamed:    eloss_calculations/aluminum_lookup_80MeV_4pc_350Torr.dat -> eloss_calculations/aluminum_lookup_80MeV_350torr_4pc.dat
	deleted:    eloss_calculations/aluminum_lookup_80MeV_3pc.dat
	deleted:    eloss_calculations/aluminum_lookup_80MeV_3pc_350Torr.dat
	new file:   eloss_calculations/fluorine_lookup_70MeV_250torr_3pc.dat
	renamed:    eloss_calculations/fluorine_lookup_70MeV_4pc.dat -> eloss_calculations/fluorine_lookup_70MeV_250torr_4pc.dat
	new file:   eloss_calculations/fluorine_lookup_70MeV_350torr_3pc.dat
	renamed:    eloss_calculations/fluorine_lookup_70MeV_4pc_350Torr.dat -> eloss_calculations/fluorine_lookup_70MeV_350torr_4pc.dat
	deleted:    eloss_calculations/fluorine_lookup_70MeV_3pc.dat
	deleted:    eloss_calculations/fluorine_lookup_70MeV_3pc_350Torr.dat
	deleted:    eloss_calculations/make_eloss_table.C
	new file:   eloss_calculations/oxygen_lookup_70MeV_250torr_3pc.dat
	renamed:    eloss_calculations/oxygen_lookup_70MeV_4pc.dat -> eloss_calculations/oxygen_lookup_70MeV_250torr_4pc.dat
	new file:   eloss_calculations/oxygen_lookup_70MeV_350torr_3pc.dat
	renamed:    eloss_calculations/oxygen_lookup_70MeV_4pc_350Torr.dat -> eloss_calculations/oxygen_lookup_70MeV_350torr_4pc.dat
	deleted:    eloss_calculations/oxygen_lookup_70MeV_3pc.dat
	deleted:    eloss_calculations/oxygen_lookup_70MeV_3pc_350Torr.dat
	deleted:    eloss_calculations/proton_lookup_20MeV_3pc.dat
	deleted:    eloss_calculations/proton_lookup_20MeV_3pc_350Torr.dat
	deleted:    eloss_calculations/proton_lookup_20MeV_4pc.dat
	deleted:    eloss_calculations/proton_lookup_20MeV_4pc_350Torr.dat
	deleted:    eloss_calculations/proton_lookup_6.0MeV.dat
2026-07-09 12:04:53 -04:00
Vignesh Sitaraman 3cfecd4c29 modified: Armory/ClassPW.h
modified:   TrackRecon.C
	modified:   run_tr.sh
2026-07-06 10:31:52 -04:00
Vignesh Sitaraman 7568431c03 modified: TrackRecon.C 2026-07-01 15:00:52 -04:00
Vignesh Sitaraman 2632044293 modified: TrackRecon.C 2026-06-29 14:33:45 -04:00
Vignesh Sitaraman 370649a7ba modified: TrackRecon.C 2026-06-29 08:55:20 -04:00
Vignesh Sitaraman 48eea6d70b modified: TrackRecon.C consolidated varaibles and implemented a method to eliminate the use of a1c0 for a1c1 calculation and report the cell pitch/ mis values for only the value chosen.
changed ranges for phi plots to -200 to 200. Folders for a1c0 and a1c1 are categorized into detector types for easier access. Using deltaphi mechanism instead of the si.phi-pc.phi formalism
    to better account for wrap around
2026-06-28 18:06:57 -04:00
Vignesh Sitaraman 826139a26d modified: TrackRecon.C changed cathode gains for the 27 Al to have consitent cfrac and other parameters for all runs. This also should allow us to
merge runs from thboth campaigns easier. Corrected error in proton mass in stuff copied over from Sudarsan's branch.
    Changed some variable names to mka ethem more consistent and clearer as to their actuall purpose.
	modified:   run_tr.sh
2026-06-28 15:43:37 -04:00
Vignesh Sitaraman 18b948a335 new file: scratch/fit_a1c0_zcorr.C not sure if this is the right apporach, doing this for now as a stopgap 2026-06-26 13:41:28 -04:00
Vignesh Sitaraman 8c10235be9 modified: .gitignore
modified:   TrackRecon.C
2026-06-26 11:14:14 -04:00
Vignesh Sitaraman 88eba525e1 modified: TrackRecon.C included new branch for True A1C0 events, A1C1 and A1C0 events now sit in different branches than the brenchmark branch, increased time gate 2026-06-26 09:52:20 -04:00
Vignesh Sitaraman aa48a9d82f modified: TrackRecon.C 2026-06-25 16:47:56 -04:00
Vignesh Sitaraman d19f0352af modified: TrackRecon.C 2026-06-25 16:12:23 -04:00
Vignesh Sitaraman 364fce5d0c modified: run_tr.sh 2026-06-25 14:03:35 -04:00
Vignesh Sitaraman d1d265835c modified: Armory/ClassPW.h
modified:   TrackRecon.C
2026-06-25 14:01:54 -04:00
Vignesh Sitaraman d784650f15 modified: Armory/ClassPW.h
new file:   CLAUDE.md
	modified:   TrackRecon.C
	modified:   run_tr.sh
2026-06-25 08:23:09 -04:00
Vignesh Sitaraman 4249b9b848 modified: Armory/ClassPW.h
modified:   TrackRecon.C replacing auto with const auto & to pass value instead of copying
2026-06-24 11:59:15 -04:00
Vignesh Sitaraman 6bad95d228 modified: Armory/ClassPW.h changed the wire phiminisation from a search based function to a phi vertex solution
modified:   TrackRecon.C changed starting aprameters for the cfrac fit, folding the lowereband from 17F into the higher band for cfrtac analysis. Exploring a new offset correction for the SX3s and QQQs based on the A1C0 Hybrid approach (WIP)
    A1C1 events are solved as A1C0 for both adjacent cells and thefinal answer with the lower Vertexperp is chosen.
	modified:   run_tr.sh reordered so that we can look at all alpha source runs as proton runs are still ebing processed
2026-06-24 10:36:23 -04:00
Vignesh Sitaraman c2a8cbefc6 modified: TrackRecon.C 2026-06-21 15:42:04 -04:00
Vignesh Sitaraman 3ba532843d modified: TrackRecon.C included stuff to account for dead wires and thus pseudo 1 wire events, cleaned up code and added comments to make the approaches more understandable
modified:   fit_a1c1_cfrac.C included a reference free method for gain amtching cell
	modified:   slope_intercept_results_17F.dat put in value for the missing wire gains based on other wires with similar profiles. The variation among them is minute but the vairation from one is consitent
2026-06-19 16:28:31 -04:00
Vignesh Sitaraman 4170adb503 modified: TrackRecon.C energy theshold of 5 on wireevent filling
modified:   run_tr.sh
2026-06-18 19:47:21 -04:00
Vignesh Sitaraman 385f5af204 modified: TrackRecon.C corrected vertexrecon_pczfix limits 2026-06-18 17:43:48 -04:00
Vignesh Sitaraman ff21920bae modified: TrackRecon.C consolidated the a1c1 linear functions and fits
new file:   fit_a1c1_cfrac.C
	modified:   run_tr.sh
2026-06-18 17:41:45 -04:00
Vignesh Sitaraman 9e2023a9db modified: TrackRecon.C
modified:   run_tr.sh
2026-06-15 19:27:41 -04:00
Vignesh Sitaraman 819a8937f7 modified: Armory/PC_StepLadder_Correction.h
modified:   TrackRecon.C benchmark a1c1 cfrac seems to work
	modified:   run_17F.sh
	modified:   run_27Al.sh
	modified:   run_tr.sh
2026-06-15 18:14:24 -04:00
Vignesh Sitaraman fcd412dc59 modified: Armory/ClassPW.h fixed typo
modified:   TrackRecon.C found some interesting behaviour in the A1c1 plots going to implement new a1c1 model invert to acount for a/c charege variation next
	modified:   scratch/plot_dither_scan.C
	modified:   scratch/scan_dither_runs.sh
2026-06-14 13:36:58 -04:00
Vignesh Sitaraman 1bbf2ae059 modified: TrackRecon.C
modified:   eloss_calculations/Eloss.py
	new file:   eloss_calculations/deutron_lookup_20MeV_3pc.dat for 27Al(a,d) pathway
	new file:   scratch/plot_dither_scan.C optimising dithering for A1C1 and A1C0 events
	new file:   scratch/scan_dither_runs.sh
	renamed:    scan_slope_runs.sh -> scratch/scan_slope_runs.sh
2026-06-12 10:42:22 -04:00
Vignesh Sitaraman 7861cc496c modified: MakeVertex.C adapted from Sudarsan's pushes
modified:   TrackRecon.C dithering was not inclded ;-;
2026-06-12 09:14:40 -04:00
Vignesh Sitaraman f7248f6a4e modified: Armory/PC_StepLadder_Correction.h
modified:   TrackRecon.C trying to benchmeark A1Cn events against a1c2 and failing due to flaww in logic
	modified:   run_tr.sh
	modified:   scratch/plot_slope_scan.C
2026-06-11 16:51:41 -04:00
Vignesh Sitaraman 20f8ad227c modified: Armory/PC_StepLadder_Correction.h
modified:   TrackRecon.C
	modified:   run_tr.sh
	modified:   scan_slope_runs.sh
	modified:   scratch/plot_slope_scan.C
2026-06-11 09:29:14 -04:00
Vignesh Sitaraman 8dd6526221 modified: TrackRecon.C bookkeeping + introducing CO2 dependent Eloss + diagnostic plots to figure out teh slope correection for the PC model_invert
new file:   eloss_calculations/alpha_lookup_20MeV_3pc_350Torr.dat
	new file:   eloss_calculations/alpha_lookup_20MeV_4pc_350Torr.dat
	new file:   eloss_calculations/aluminum_lookup_80MeV_3pc_350Torr.dat
	new file:   eloss_calculations/aluminum_lookup_80MeV_4pc_350Torr.dat
	new file:   eloss_calculations/fluorine_lookup_70MeV_3pc_350Torr.dat
	new file:   eloss_calculations/fluorine_lookup_70MeV_4pc_350Torr.dat
	new file:   eloss_calculations/oxygen_lookup_70MeV_3pc_350Torr.dat
	new file:   eloss_calculations/oxygen_lookup_70MeV_4pc_350Torr.dat
	new file:   eloss_calculations/proton_lookup_20MeV_3pc_350Torr.dat
	new file:   eloss_calculations/proton_lookup_20MeV_4pc_350Torr.dat
	modified:   run_tr.sh book keeping
	new file:   scan_slope_runs.sh   diagnostic plots to figure out the slope correection for the PC model_invert
	new file:   scratch/plot_slope_scan.C  diagnostic plots to figure out the slope correection for the PC model_invert
2026-06-09 17:37:22 -04:00
Vignesh Sitaraman 948c6e6ea2 renamed: Calibration.C -> CalibrationQQQ.C changed name to make the calibration script explicitly state the kind of detectors QQQ
renamed:    Calibration.h -> CalibrationQQQ.h
	modified:   README.md
2026-06-08 11:48:00 -04:00
Vignesh Sitaraman 5824fa7148 modified: TrackRecon.C made variables to account for variable energy loss in 27Al and 17F runs due to beamline components
modified:   run_17F.sh made all outputs direct to specific folders for clarity and to avoid overwriting results from different datasets
	modified:   run_27Al.sh made output folder format consitent across datasets
	modified:   run_tr.sh made output folder format consitent across datasets
2026-06-08 11:32:39 -04:00
Vignesh Sitaraman 20dc8fef22 modified: TrackRecon.C
modified:   run_tr.sh parralelistaion of all runs and addition of CO2 percent as an environment variable
2026-06-08 10:39:22 -04:00
Vignesh Sitaraman 702399be84 modified: Calibration.C corrected the p energy being used to the 241Am peak
modified:   GainMatchQQQ.C made all output files .dat instead of .txt
	modified:   TrackRecon.C made ome more plots for dissertation
	modified:   qqq_Calib.dat updated with 241Am peak position
	modified:   run_17F.sh
	modified:   run_tr.sh
	modified:   scratch/make_prettyplots.C made change so now we can input multiple runs at once and plots them together
2026-06-07 17:18:44 -04:00
Vignesh Sitaraman 9ad4e9d5d4 modified: scratch/make_prettyplots.C 2026-06-05 19:47:05 -04:00
Vignesh Sitaraman 7891aaebca modified: scratch/scan_rf_timing.C output images instead of gif 2026-06-05 15:41:32 -04:00
Vignesh Sitaraman d8e4b22614 modified: TrackRecon.C seprating rf-mcp time for qqq into inner vs outer rings 2026-06-05 11:06:49 -04:00
Vignesh Sitaraman d5419bab9b new file: anasen_fem/1dpotplot.py 1d potential plotter from A to C from elmer output
# modified:   anasen_fem/wires_gmsh2d_bc.py
	new file:   scratch/scan_rf_timing.C scan RF-MCP timing for runs to look at variation
2026-06-05 11:05:40 -04:00
Vignesh Sitaraman 66fd758554 modified: scratch/make_prettyplots.C set z min 2026-06-05 08:48:42 -04:00
Vignesh Sitaraman 88cf59bce3 modified: anasen_fem/paraview_plotter.py correct path for zephyrus 2026-06-04 15:59:13 -04:00
Vignesh Sitaraman 86933ac2bf modified: TrackRecon.C
modified:   eloss_calculations/Eloss.py changes to accoodate 3%CO2 mix instead of 4%CO2 mix
2026-06-04 15:35:04 -04:00
Vignesh Sitaraman a875b17247 modified: TrackRecon.C
modified:   run_tr.sh
	modified:   scratch/make_prettyplots.C
2026-06-04 14:32:33 -04:00
Vignesh Sitaraman 6104c6f7a9 modified: TrackRecon.C
modified:   run_17F.sh
	renamed:    scratch/make_pretty.C -> scratch/make_prettyplots.C
2026-06-04 08:15:16 -04:00
Vignesh Sitaraman 1fb12d2f46 modified: Armory/HistPlotter.h changes to make histgrams plot in alphabetical order
modified:   TrackRecon.C changes to maek the misc branches work
	modified:   TrackRecon.h changes to maek the misc branches work
	modified:   run_17F.sh
2026-06-03 15:38:00 -04:00
Vignesh Sitaraman 792933de25 modified: TrackRecon.C made to changes to make the old analysis histograms switchable. Having problems with the misc branch addresses for 17F reaction data analysis.
modified:   TrackRecon.h
2026-06-03 14:42:16 -04:00
Vignesh Sitaraman a64d45e081 modified: TrackRecon.C changed the nA analyssis to be a little more efficient
modified:   run_17F.sh
2026-06-03 11:46:07 -04:00
Vignesh Sitaraman 254402b4cc new file: scratch/make_pretty.C make pretty plots for the thesis 2026-06-02 18:35:39 -04:00
Vignesh Sitaraman 787b1ca498 new file: scratch/PhiCorr.C
renamed:    anasen_labels.csv -> scratch/anasen_labels.csv
	renamed:    grid_generate.py -> scratch/grid_generate.py
	renamed:    shadowplay.py -> scratch/shadowplay.py
2026-05-29 13:32:32 -04:00
Vignesh Sitaraman 15773d4606 modified: TrackRecon.C
modified:   run_27Al.sh
	modified:   run_tr.sh
2026-05-26 15:43:21 -04:00
Vignesh Sitaraman 07fe2a5d38 modified: TrackRecon.C qqq.event recon typo corrected 2026-05-26 08:55:35 -04:00
Vignesh Sitaraman 3b70b279e7 modified: run_17F.sh
modified:   run_tr.sh
2026-05-20 15:03:46 -04:00
Vignesh Sitaraman f5f7515d7a modified: TrackRecon.C partly cleaned up analysis code
modified:   TrackRecon.h
	new file:   run_tr.sh
	modified:   scratch/sx3z_vs_phiz/scan_offset.C
	modified:   scratch/sx3z_vs_phiz/scan_offset_fix.C
2026-05-20 14:58:36 -04:00
Vignesh Sitaraman 41b286da5d modified: MakeVertex.C
modified:   anasen_fem/run.py
	modified:   anasen_fem/scalars.dat.names
	modified:   run_sx3.sh
	new file:   slope_intercept_results.dat
2026-05-20 09:36:53 -04:00
Vignesh Sitaraman bb05baf89d modified: Armory/ClassPW.h changes made to explain the andoe and cathode shifts in a more intuitive geometric manner
modified:   MakeVertex.C changed code to make nA plots instead of nA0C to add more stats to n anode analysis
	modified:   anasen_fem/paraview_plotter.py changed the analysis to plot every 32nd field line, dure to indreaed field density from the new wire shift
	modified:   anasen_fem/run.py going from 0 to 174.6 in 17.43 increments to account for the remeasured lenth of the pc
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires_gmsh2d_bc.py length of pc changed, 4 wire shift incorporated, set mesh order to 2 to decrease the meashing density
    pccal folder seems to make 17F analysis work, not sure why still trying to figure it out
	new file:   pccal/anode_gainmatch.C
	new file:   pccal/anode_gm_coeffs.dat
	new file:   pccal/cathode_gainmatch.C
	new file:   pccal/cathode_gm_coeffs.dat
	new file:   pccal/pc_gm_coeffs.dat
	new file:   pccal/slope_intercept_26Al.dat
    scratch folder analysis for pcz vs pczfix analysis from sudarsan's branch
	new file:   scratch/sx3z_vs_phiz/scan_offset.C
	new file:   scratch/sx3z_vs_phiz/scan_offset_fix.C
2026-05-19 17:57:54 -04:00
Vignesh Sitaraman d8593b2f55 modified: MakeVertex.C
modified:   anasen_fem/run.py
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires_gmsh2d_bc.py
2026-05-19 10:28:41 -04:00
Vignesh Sitaraman ce0bedf704 deleted: Armory/ClassPC1An.h delete4d duplicate
modified:   Armory/ClassPW.h changes made for 4 wire shift to the anode and cathode starting positions
	modified:   Armory/PC_StepLadder_Correction.h
	modified:   anasen_fem/paraview_plotter.py corrected path for new pc
	modified:   run_17F.sh
	modified:   run_27Al.sh
	modified:   run_sx3.sh
2026-05-18 17:46:20 -04:00
Vignesh Sitaraman b69dcf39d6 modified: MakeVertex.C
modified:   README.md
	modified:   anasen_fem/run.py
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires_gmsh2d_bc.py
	modified:   run_sx3.sh
2026-05-15 18:01:31 -04:00
Vignesh Sitaraman 17f44bc12e modified: README.md
modified:   run_27Al.sh
2026-05-15 14:57:12 -04:00
Vignesh Sitaraman 3503953b0f modified: MakeVertex.C
new file:   README.md WIP but I think this is a good start
	modified:   run_sx3.sh
2026-05-15 14:45:57 -04:00
Vignesh Sitaraman c142f4b567 deleted: Analyzer1.C
deleted:    Analyzer1.h
	deleted:    GainMatchSX3.C
	deleted:    GainMatchSX3.h
	deleted:    GainMatchSX3Front.C
	deleted:    GainMatchSX3Front.h
	deleted:    GainMatchSX3Front1.C
	deleted:    sx3_BackGains.txt
	deleted:    sx3_GainMatchfront.txt
    Book keeping deleting older unused scripts.
2026-05-15 14:02:00 -04:00
Vignesh Sitaraman 574506acb7 modified: Armory/ClassPW.h
modified:   Armory/PC_StepLadder_Correction.h incorp[orating 4 wire twist]
	modified:   MakeVertex.C
2026-05-15 11:14:52 -04:00
Vignesh Sitaraman 419cbd3c8c modified: MakeVertex.C psuedo excitation function for th 27Al using the single anode wire events, DOES NOT WORK YET needs to be fixed
# modified:   run_27Al.sh
2026-05-12 16:37:23 -04:00
Vignesh Sitaraman 5282ef7e1c Merge branch 'devel_vignesh' of https://fsunuc.physics.fsu.edu/git/rtang/ANASEN_analysis into devel_vignesh 2026-05-12 13:40:08 -04:00
Vignesh Sitaraman 1d7b9dde47 modified: MakeVertex.C
modified:   eloss_calculations/Eloss.py making lookup tables for aluminum, fluorine, and oxygen
	new file:   eloss_calculations/aluminum_lookup_80MeV.dat
	new file:   eloss_calculations/fluorine_lookup_70MeV.dat
	new file:   eloss_calculations/oxygen_lookup_70MeV.dat
2026-05-12 13:39:38 -04:00
Vignesh Sitaraman 1081e4b690 modified: MakeVertex.C
modified:   run_27Al.sh
	modified:   run_sx3.sh
2026-05-11 17:23:43 -04:00
Vignesh Sitaraman 4dd157bcb8 modified: Armory/SX3Geom.h
modified:   MakeVertex.C
	modified:   MakeVertex.h
	modified:   run_sx3.sh
	modified:   sx3cal/27Al/backgains.dat
	new file:   sx3cal/27Al/backgains.dat.Apr2026
	modified:   sx3cal/27Al/frontgains.dat.unity
2026-05-11 14:01:17 -04:00
Vignesh Sitaraman 164a3e2e57 Merge branch 'devel_vignesh' of https://fsunuc.physics.fsu.edu/git/rtang/ANASEN_analysis into devel_vignesh 2026-05-11 13:56:53 -04:00
Vignesh Sitaraman 3a42c2d137 modified: Armory/ClassPW.h
modified:   MakeVertex.C
	modified:   run_sx3.sh
2026-05-11 13:56:44 -04:00
Vignesh Sitaraman 2908da4854 modified: .gitignore
new file:   Armory/EventBuilder.cpp
	modified:   MakeVertex.C
	modified:   run_sx3.sh
2026-05-09 17:14:01 -04:00
Vignesh Sitaraman 9d581fa72d new file: anasen_labels.csv
new file:   detector_geometry.dat
	new file:   eloss_calculations/Eloss.py
	new file:   eloss_calculations/alpha_lookup_20MeV.dat
	new file:   eloss_calculations/alpha_lookup_6.0MeV.dat
	new file:   eloss_calculations/make_eloss_table.C
	new file:   eloss_calculations/proton_lookup_20MeV.dat
	new file:   eloss_calculations/proton_lookup_6.0MeV.dat
	new file:   grid_generate.py
	new file:   shadowplay.py
2026-05-08 16:42:36 -04:00
Vignesh Sitaraman c8923ca870 modified: run_sx3.sh 2026-05-05 16:44:40 -04:00
Vignesh Sitaraman d43edcf2ee modified: MakeVertex.C 2026-05-05 16:44:28 -04:00
Vignesh Sitaraman e25a63cd14 deleted: pccal/anode_gainmatch.C
deleted:    pccal/anode_gm_coeffs.dat
	deleted:    pccal/cathode_gainmatch.C
	deleted:    pccal/cathode_gm_coeffs.dat
	deleted:    pccal/slope_intercept_26Al.dat
	deleted:    scratch/sx3z_vs_phiz/scan_offset.C
	deleted:    scratch/sx3z_vs_phiz/scan_offset_fix.C
	deleted:    scratch/sx3z_vs_phiz/stitch.C
	deleted:    scratch/sx3z_vs_phiz/testmodel.h
	deleted:    scratch/test_eloss.h
	renamed:    pccal/pc_gm_coeffs.dat -> slope_intercept_results_17F.dat
2026-05-05 16:41:11 -04:00
Vignesh Sitaraman 3f55a2a81e new file: Armory/Kinematics.cpp
new file:   Armory/Kinematics.h
	new file:   Armory/PC_StepLadder_Correction.h
	modified:   BatchProcess.sh
	deleted:    ELoss/Eloss.py
	deleted:    ELoss/Eloss_17F
	deleted:    ELoss/Eloss_27Al
	deleted:    ELoss/Eloss_alpha
	deleted:    ELoss/Eloss_p
	deleted:    ELoss/alpha_lookup_20MeV.dat
	deleted:    ELoss/alpha_lookup_6.0MeV.dat
	deleted:    ELoss/proton_lookup_20MeV.dat
	deleted:    ELoss/proton_lookup_6.0MeV.dat
	modified:   MakeVertex.C
2026-05-01 12:01:42 -04:00
Vignesh Sitaraman 15e60a0cc1 Merge branch 'devel_vignesh' of https://fsunuc.physics.fsu.edu/git/rtang/ANASEN_analysis into devel_vignesh 2026-04-27 18:24:06 -04:00
Vignesh Sitaraman 4a7dc22acd modified: Armory/ClassDet.h
modified:   BatchProcess.sh
	modified:   MakeVertex.C
	modified:   ProcessRun.sh
	modified:   run_sx3.sh
2026-04-27 18:23:55 -04:00
Vignesh Sitaraman e41f2e14ec modified: .gitignore 2026-04-27 17:59:42 -04:00
Vignesh Sitaraman 40ec71a216 modified: anasen_fem/garfield_sim.py mad
modified:   anasen_fem/run.py
	modified:   anasen_fem/wires_gmsh2d_bc.py
    made changes to both to resolve inconsistency between the mesh generated by GMSH (3nodes) and expected by garfield (10nodes)
2026-04-27 17:59:42 -04:00
Vignesh Sitaraman dccea0c862 modified: anasen_fem/garfield_sim.py
modified:   anasen_fem/paraview_plotter.py
2026-04-27 14:17:09 -04:00
Vignesh Sitaraman fc09dc9258 Merge branch 'devel_vignesh' of https://fsunuc.physics.fsu.edu/git/rtang/ANASEN_analysis into devel_vignesh 2026-04-27 13:57:54 -04:00
Vignesh Sitaraman 16c49c4f12 modified: Armory/ClassDet.h
modified:   Armory/Mapper.cpp
	modified:   mapping.h
    made changes to allow misc det type to be read in
	modified:   ProcessRun.sh added file paths in diferent pcs
	modified:   anasen_fem/garfield_sim.py
2026-04-27 13:52:27 -04:00
Vignesh Sitaraman c3bb28a1a2 modified: Armory/ClassDet.h
modified:   Armory/Mapper.cpp
    made changes to channel map and Detector class to include misc channels( MCP, RF, IC etc) and fine timing information.
2026-04-25 12:34:05 -04:00
Vignesh Sitaraman 307d5dfc44 new file: anasen_fem/dielectrics.dat
modified:   anasen_fem/garfield_sim.py
2026-04-25 12:26:45 -04:00
Vignesh Sitaraman 1a01f332e6 Merge branch 'devel_vignesh' of https://fsunuc.physics.fsu.edu/git/rtang/ANASEN_analysis into devel_vignesh 2026-04-24 14:36:31 -04:00
Vignesh Sitaraman e3bfcda35c modified: anasen_fem/garfield_sim.py changed mesh input for garfield 2026-04-24 14:34:50 -04:00
Vignesh Sitaraman 67bb9b6fd9 modified: .gitignore
modified:   anasen_fem/paraview_plotter.py
	modified:   anasen_fem/wires2d.sif
	modified:   anasen_fem/wires_gmsh2d_bc.py
2026-04-24 14:31:50 -04:00
Vignesh Sitaraman b936da724a modified: .gitignore
modified:   ELoss/Eloss.py  made changes to generate a ELoss lookup table instead of Range and dE/dx
	new file:   ELoss/alpha_lookup_20MeV.dat
	new file:   ELoss/alpha_lookup_6.0MeV.dat
	new file:   ELoss/proton_lookup_20MeV.dat
	new file:   ELoss/proton_lookup_6.0MeV.dat
2026-04-23 17:21:52 -04:00
Vignesh Sitaraman 8e2cdaae58 modified: ELoss/Eloss.py missed a line while editing the file 2026-04-22 14:48:14 -04:00
Vignesh Sitaraman 50a8e03eef modified: .gitignore
new file:   ELoss/Eloss.py made a Eloss calculator using the pyCatima library
	new file:   ELoss/alpha_loss_250torr.dat
	new file:   ELoss/proton_loss_250torr.dat
	modified:   MakeVertex.C
2026-04-22 14:46:48 -04:00
Vignesh Sitaraman 6e0100253b modified: MakeVertex.C
modified:   anasen_fem/garfield_sim.py
	new file:   run_17F.sh
	new file:   run_27Al.sh
	new file:   scratch/test_eloss.h
2026-04-20 11:37:33 -04:00
Vignesh Sitaraman 4c8e3b7519 modified: MakeVertex.C 2026-04-17 12:47:20 -04:00
Vignesh Sitaraman b801421d3c modified: MakeVertex.C changed to Sudarsan's MakeVertex.C
modified:   TrackRecon.C changed to my MakeVertex.C
	modified:   run_sx3.sh
	new file:   scratch/sx3z_vs_phiz/testmodel.h required to run Sudarsan's version of MakeVertex.C
2026-04-15 13:34:14 -04:00
Vignesh Sitaraman 45ab7f9cee new file: anasen_fem/garfield_sim.py
modified:   anasen_fem/run.py
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires_gmsh2d_bc.py
	new file:   run_sx3.sh
2026-04-14 16:05:06 -04:00
Vignesh Sitaraman 3999fd5b71 modified: .gitignore
modified:   anasen_fem/scalars.dat.names
2026-04-02 14:25:13 -04:00
Vignesh Sitaraman e407b9842e modified: anasen_fem/run.py added line sto archive the simulation files to save space.
modified:   anasen_fem/wires_gmsh2d_bc.py made it refine twice instead of doing a weighed refinement to get a faster runtime. The losses in precision aren't too bad.
2026-04-02 14:11:03 -04:00
Vignesh Sitaraman 00c8a9378e modified: anasen_fem/run.py
modified:   anasen_fem/scalars.dat
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires2d.sif
	modified:   anasen_fem/wires_gmsh2d_bc.py included IC and hot needle to simulations
2026-04-01 17:42:53 -04:00
Vignesh Sitaraman 652b680fb9 modified: anasen_fem/paraview_plotter.py made changes to allow field lines to only originate fom equipotential lines. 2026-03-31 17:24:23 -04:00
Vignesh Sitaraman 74dfc46d8c modified: .gitignore
modified:   anasen_fem/paraview_plotter.py included code to make and save field plots
	modified:   anasen_fem/run.py included changes for parapview plotter and also save all outputs for mesh and elmer in folders
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires_gmsh2d_bc.py
2026-03-31 13:34:12 -04:00
Vignesh Sitaraman 5b34251638 modified: anasen_fem/run.py
modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires_gmsh2d_bc.py
2026-03-31 10:16:28 -04:00
Vignesh Sitaraman 68efdadc8f modified: sx3cal/EXFit.C
modified:   sx3cal/LRFit.C
2026-03-30 09:52:31 -04:00
Vignesh Sitaraman e0f2fa192c modified: MakeVertex.C
modified:   MatchAndPlotCentroids.C
	modified:   anasen_fem/scalars.dat.names
	deleted:    centroids.txt
	renamed:    slope_intercept_cathode.dat -> slope_intercept_cathode_27Al.dat
	renamed:    slope_intercept_results.dat -> slope_intercept_results_27Al.dat
	renamed:    slope_intercept_results_anode.dat -> slope_intercept_results_anode_27Al.dat
2026-03-25 16:50:59 -04:00
Vignesh Sitaraman 456db0a9d0 modified: .gitignore
modified:   anasen_fem/paraview_plotter.py increase line width and resolution for better visualization
	modified:   anasen_fem/run.py
	modified:   anasen_fem/scalars.dat.names
	modified:   anasen_fem/wires2d.sif
	modified:   anasen_fem/wires_gmsh2d_bc.py
2026-03-23 17:48:26 -04:00
Vignesh Sitaraman ec9d25b048 modified: .gitignore
modified:   Armory/ClassPW.h new geo + crossover moved to PW.h
	modified:   MakeVertex.C added plots
	new file:   anasen_fem/README.md
	new file:   anasen_fem/clean.sh
	new file:   anasen_fem/junk/wires.py
	new file:   anasen_fem/junk/wires2d_test.sif
	new file:   anasen_fem/junk/wires_gmsh.py changed wire radius from Sudarsan's version
	new file:   anasen_fem/junk/wires_gmsh_bc.py
	new file:   anasen_fem/paraview_plotter.py
	new file:   anasen_fem/run.py
	new file:   anasen_fem/scalars.dat
	new file:   anasen_fem/scalars.dat.names
	new file:   anasen_fem/wires2d.sif
	new file:   anasen_fem/wires_gmsh2d_bc.py
2026-03-16 14:22:35 -04:00
Vignesh Sitaraman 65af941b39 modified: Armory/ClassPW.h 2026-03-09 14:24:44 -04:00
Vignesh Sitaraman 9af7e70f26 modified: MakeVertex.C 2026-03-06 16:09:28 -05:00
Vignesh Sitaraman 6e6d281dd3 modified: MakeVertex.C hist scale changed 2026-03-06 16:00:27 -05:00
Vignesh Sitaraman 411ef2d9de modified: MakeVertex.C implemented diagnostics to compare the behaviour of singleton cathodes vs events with higher multiplicty 2026-03-06 15:56:48 -05:00
Vignesh Sitaraman cbd4bf42a7 modified: MakeVertex.C 2026-02-26 12:42:02 -05:00
Vignesh Sitaraman 601caa3881 modified: MakeVertex.C 2026-02-24 21:06:24 -05:00
Vignesh Sitaraman 2938411c35 modified: .gitignore
new file:   ELoss/Eloss_17F
	new file:   ELoss/Eloss_27Al
	new file:   ELoss/Eloss_alpha
	new file:   ELoss/Eloss_p
	modified:   MakeVertex.C
	deleted:    MakeVertex.C:Zone.Identifier
	deleted:    MakeVertex.h:Zone.Identifier
2026-02-24 11:59:01 -05:00
Vignesh Sitaraman 8c2657255c modified: Armory/ClassPW.h
new file:   Armory/SX3Geom.h
	modified:   MakeVertex.C
	renamed:    sx3cal/sx3cal/EXFit.C -> sx3cal/EXFit.C
	renamed:    sx3cal/sx3cal/LRFit.C -> sx3cal/LRFit.C
	renamed:    sx3cal/sx3cal/backgains.dat -> sx3cal/backgains.dat
	renamed:    sx3cal/sx3cal/backgains.dat.unity -> sx3cal/backgains.dat.unity
	renamed:    sx3cal/sx3cal/frontgains.dat -> sx3cal/frontgains.dat
	renamed:    sx3cal/sx3cal/frontgains.dat.unity -> sx3cal/frontgains.dat.unity
	renamed:    sx3cal/sx3cal/rightgains.dat -> sx3cal/rightgains.dat
	renamed:    sx3cal/sx3cal/rightgains.dat.unity -> sx3cal/rightgains.dat.unity
2026-02-19 14:49:49 -05:00
Vignesh Sitaraman 00f8460e36 modified: MakeVertex.C
new file:   sx3cal/sx3cal/EXFit.C
	new file:   sx3cal/sx3cal/LRFit.C
	new file:   sx3cal/sx3cal/backgains.dat
	new file:   sx3cal/sx3cal/backgains.dat.unity
	new file:   sx3cal/sx3cal/frontgains.dat
	new file:   sx3cal/sx3cal/frontgains.dat.unity
	new file:   sx3cal/sx3cal/rightgains.dat
	new file:   sx3cal/sx3cal/rightgains.dat.unity
2026-02-18 16:01:55 -05:00
Vignesh Sitaraman 7260d42d8d modified: Armory/ANASEN_model.C
modified:   Armory/ClassPW.h
	modified:   MakeVertex.C
	modified:   TrackRecon.C
2026-02-18 12:06:54 -05:00
Vignesh Sitaraman 4401ae8eb2 new file: MakeVertex.C
new file:   MakeVertex.C:Zone.Identifier
	new file:   MakeVertex.h
	new file:   MakeVertex.h:Zone.Identifier
	modified:   TrackRecon.C
2026-02-11 15:08:11 -05:00
Vignesh Sitaraman 282aa5ecea modified: .gitignore
new file:   Armory/ClassData.h
	new file:   Armory/Hit.h
	modified:   Armory/Makefile
	new file:   Armory/fsuReader.h
	new file:   Armory/macro.h
	new file:   BatchProcess.sh
	modified:   ProcessRun.sh
	modified:   process_mapped_run.sh
2026-02-10 17:01:27 -05:00
Vignesh Sitaraman 9f949edd00 new file: RunTimeSummary.C
new file:   Timing_Summary_Matplotlib.png
	modified:   TrackRecon.C
	modified:   process_mapped_run.sh
2026-02-09 16:11:07 -05:00
Vignesh Sitaraman 56cc900b61 modified: .gitignore
modified:   TrackRecon.C
	deleted:    batchproces_mapped_run.sh
	modified:   process_mapped_run.sh
2026-02-05 15:20:17 -05:00
Vignesh Sitaraman 17ab8c884a modified: TrackRecon.C
new file:   batchproces_mapped_run.sh
	new file:   process_mapped_run.sh
2026-01-30 10:53:34 -05:00
Vignesh Sitaraman 67199cdb60 modified: QQQ_Calcheck.C
modified:   TrackRecon.C
	new file:   qqq_Calib.dat
	new file:   qqq_GainMatch.dat
	renamed:    slope_intercept_cathode.txt -> slope_intercept_cathode.dat
	renamed:    slope_intercept_results.txt -> slope_intercept_results.dat
	renamed:    slope_intercept_results_anode.txt -> slope_intercept_results_anode.dat
2026-01-28 14:27:42 -05:00
Vignesh Sitaraman ac035370b4 modified: QQQ_Calcheck.C made changes to bring it in line with the new consistent Wedge-Ring mapping
modified:   TrackRecon.C
2026-01-25 14:15:45 -05:00
Vignesh Sitaraman c4b543bdeb modified: ProcessRun.sh
modified:   TrackRecon.C
	modified:   mapping.h corrrrected QQQ0 rings
2026-01-25 11:23:27 -05:00
Vignesh Sitaraman 0a8432e4e3 modified: TrackRecon.C phi and theta plots for PC and QQQ included 2026-01-23 17:55:55 -05:00
Vignesh Sitaraman 0883ebdb6e modified: Armory/Makefile
deleted:    Armory/README.md
	modified:   Calibration.C Sudarsan pointed out that the gain match and calibration stages have the ring and wedge swapped, so I fixed that.
	modified:   ProcessRun.sh changes for running on laptop
	modified:   TrackRecon.C same inconsistency as in Calibration.C fixed
	deleted:    makeplots.C not used anymore
	modified:   mapping.h corrected teh mapping for the QQQs poptentially, need to confirm
	modified:   mapping_old.txt
2026-01-22 15:07:10 -05:00
Vignesh Sitaraman 9c20c4abfe modified: TrackRecon.C QQQ wedge channels flipped but the energy gains have not, thus QQQ energy needs to be recalibrated. 2026-01-21 11:56:32 -05:00
Vignesh Sitaraman 13bfafe9c4 modified: Armory/ClassPW.h
modified:   TrackRecon.C
2026-01-18 15:41:54 -05:00
Vignesh Sitaraman 22e32c7ebc Refactor plotting logic in TrackRecon::Process for clarity and added neighbour checks for anode and cathode hits 2026-01-16 16:36:25 -05:00
Vignesh Sitaraman 4599ad2a38 modified: TrackRecon.C 2026-01-13 17:55:27 -05:00
Vignesh Sitaraman c1ffaa8340 modified: TrackRecon.C 2026-01-13 17:51:01 -05:00
Vignesh Sitaraman 19286055ea modified: TrackRecon.C inlcuded timing plots for the PC 2026-01-13 12:04:14 -05:00
Vignesh Sitaraman 82c2127b4d modified: TrackRecon.C included test cases for 1,2,&3 cathode events. Also stopped sorting the cathode anmd anodehits arrays. 2026-01-09 15:49:32 -05:00
Vignesh Sitaraman d81e35d5e4 modified: Analyzer.C
modified:   TrackRecon.C Reconstruction only for the QQQ tracks
	new file:   TrackRecon.h
2025-12-19 11:56:10 -05:00
Vignesh Sitaraman 97880940be modified: .gitignore
modified:   .vscode/settings.json
	modified:   Analyzer.C
	modified:   Calibration.C
	modified:   GainMatchQQQ.C
	modified:   QQQ_Calcheck.C
2025-12-16 15:41:21 -05:00
Vignesh Sitaraman aee3a2467d modified: Calibration.C
modified:   GainMatchQQQ.C
	modified:   QQQ_Calcheck.C
	modified:   makeplots.C
2025-12-01 13:49:23 -05:00
Vignesh Sitaraman c32215e293 modified: .vscode/settings.json
modified:   Calibration.C
	modified:   GainMatchQQQ.C
	new file:   QQQ_Calcheck.C
	new file:   QQQ_Calcheck.h
	new file:   makeplots.C
2025-11-26 11:32:16 -05:00
Vignesh Sitaraman 535afcb704 modified: Calibration.C
modified:   GainMatchQQQ.C
2025-11-17 18:33:11 -05:00
Vignesh Sitaraman 0773b9e6cc modified: .gitignore
modified:   .vscode/settings.json
	renamed:    HistPlotter.h -> Armory/HistPlotter.h
	new file:   Armory/LICENSE
	new file:   Armory/README.md
	modified:   Calibration.C
	modified:   GainMatchQQQ.C
	modified:   GainMatchSX3.C
	modified:   sx3_GainMatchfront.txt
2025-11-17 09:33:08 -05:00
Vignesh Sitaraman 7582731de4 new file: sx3_BackGains.txt
new file:   sx3_GainMatchfront.txt
2025-10-29 17:47:40 -04:00
Vignesh Sitaraman 49de3b64a8 modified: Analyzer.C
modified:   GainMatchSX3.C
	modified:   GainMatchSX3Front.C
	new file:   HistPlotter.h
2025-10-29 17:42:54 -04:00
Vignesh Sitaraman 61473ca14e modified: Calibration.C use both front and back gains
modified:   GainMatchSX3.C changed structure a bit
	modified:   GainMatchSX3Front.C removed some redundant code that I was trying out
2025-10-06 15:11:31 -04:00
Vignesh Sitaraman ecd755e09c modified: Calibration.C looking at 1d hists for sx3 backs 2025-09-30 15:45:16 -04:00
Vignesh Sitaraman 265ebd3372 modified: Calibration.C
modified:   GainMatchQQQ.C
	modified:   GainMatchSX3.C
	modified:   GainMatchSX3Front.C trying out not doing back gainmatching to see if that improves fits.
2025-09-30 15:17:00 -04:00
Vignesh Sitaraman afef56df12 modified: Analyzer.C
modified:   GainMatchSX3.C
2025-09-22 13:31:22 -04:00
Vignesh Sitaraman 579f4e4f6c modified: .vscode/settings.json
modified:   GainMatchSX3.C to make the calib a 2 factor calib insteade of inlcuding the fronts
	modified:   GainMatchSX3Front.C chcanged the readout for the  new back calib
2025-09-18 13:28:02 -04:00
Vignesh Sitaraman d59b22ff78 modified: Calibration.C 2025-09-17 13:42:12 -04:00
Vignesh Sitaraman 49610e9c2f modified: Calibration.C 2025-09-17 13:22:11 -04:00
Vignesh Sitaraman fa4b1dd2f5 new file: Calibration.C
renamed:    GainMatch.h -> Calibration.h
	renamed:    GainMatch.C -> GainMatchQQQ.C
	new file:   GainMatchQQQ.h
2025-09-04 14:56:55 -04:00
Vignesh Sitaraman 877f765357 modified: GainMatchSX3Front.C 2025-08-20 17:09:01 -07:00
Vignesh Sitaraman 06fbc1afd9 modified: GainMatchSX3.C
modified:   GainMatchSX3Front.C
2025-08-20 15:25:40 -07:00
Vignesh Sitaraman b44ffd7fdf modified: .vscode/c_cpp_properties.json made changes to include the laptop
modified:   GainMatchSX3.C included flags to allow interactive mode and verbose fit
	modified:   GainMatchSX3Front.C included flags to allow interactive mode and verbose fit
2025-07-31 12:07:07 -04:00
Vignesh Sitaraman 3d0d176f5a modified: GainMatchSX3.C
modified:   GainMatchSX3Front.C
    changes made to the GainMatchSX3.C and GainMatchSX3Front.C files to include reduced Chisquared and fixed uncertainties for the gain matching process.
2025-07-24 16:12:46 -04:00
Vignesh Sitaraman 4fc05ea338 new file: GainMatchSX3Front.C using a 2 step fit for the same method, going to implement a inverse fit now wherein the fronts are fit first and then the sum is fit against the backs.
new file:   GainMatchSX3Front.h
	new file:   GainMatchSX3Front1.C
2025-07-21 11:19:27 -04:00
Vignesh Sitaraman dd2ec66db1 modified: GainMatchSX3.C multidimfit now runs but does not work as expected,
the fit curve is empty.
2025-07-09 15:30:12 -04:00
Vignesh Sitaraman a8d4e8f0f6 modified: GainMatchSX3.C multidimfit WIP 2025-07-08 13:53:00 -04:00
Vignesh Sitaraman 2864036ec8 fix: correct include path formatting in c_cpp_properties.json 2025-06-10 11:31:08 -04:00
Vignesh Sitaraman 050cb425d5 modified: GainMatchSX3.C 2025-06-10 11:24:01 -04:00
Vignesh Sitaraman fb355a3cc4 modified: GainMatchSX3.C
changes made to GainMatchSX3  when I found a bug in the way the sx3 condition was being checked
2025-06-10 11:18:08 -04:00
Vignesh Sitaraman 5b43d60b30 modified: GainMatchSX3.C changed terminate to accomodate for events which don't have a back but have more than 3 SX3hits 2025-05-27 13:29:01 -04:00
Vignesh Sitaraman e86ab5ed4d modified: GainMatchSX3.C gainmatching of backs fixed. fronts in progress 2025-05-19 13:16:22 -04:00
Vignesh Sitaraman 9cadfdd191 modified: GainMatchSX3.C 2025-05-13 13:32:22 -04:00
Vignesh Sitaraman d4582d80ff modified: GainMatch.C
new file:   GainMatchSX3.C
	new file:   GainMatchSX3.h
2025-05-12 17:21:25 -04:00
Vignesh Sitaraman 18870ed82b modified: GainMatch.C 2025-04-25 16:18:58 -04:00
Vignesh Sitaraman 5c1c5348f4 modified: GainMatch.C QQQs now show up as gain matched. 2025-04-25 15:41:10 -04:00
Vignesh Sitaraman 65ab69ebe6 modified: GainMatch.C 2025-04-24 10:48:14 -04:00
Vignesh Sitaraman 1df7470ca1 modified: .vscode/settings.json 2025-04-10 09:51:36 -04:00
Vignesh Sitaraman a7a765c059 modified: Analyzer.C
new file:   GainMatch.C
	new file:   GainMatch.h
2025-04-10 09:50:54 -04:00
Vignesh Sitaraman 39e8f41ab1 modified: Analyzer.C implemented basic trackreconstruction
modified:   Armory/ANASEN_model.C changed qqq radii
	modified:   Armory/ClassPW.h implemented basic trackreconstruction
2025-02-27 10:34:41 -05:00
Vignesh Sitaraman 9225620426 modified: Analyzer.C
modified:   Armory/ClassPW.h edited to account for the 4 wire offset instead of 3 in cathodes. This has been crossreferenced using the alpha source data in QQQ coinincidence to confirm
    the position of the source.
2025-02-21 15:40:52 -05:00
Vignesh Sitaraman 2225b3a942 modified: .gitignore 2025-02-17 17:06:33 -05:00
Vignesh Sitaraman 6cfb38b564 modified: Analyzer.C 2025-02-17 17:03:58 -05:00
Vignesh Sitaraman cb72c14ca4 modified: Analyzer.C modfied the algorithm for selection of valid cathodes, the section is now based on geometry
modified:   Armory/ClassPW.h the rotation of the cathodes was reversed
2025-02-17 16:59:08 -05:00
Vignesh Sitaraman 5995081396 modified: Analyzer.C
modified:   Armory/ClassPW.h
    adjusted the Cathode geometry to  incorporate the offsett of 3 wires
2025-02-05 14:59:02 -05:00
Vignesh Sitaraman d623e0cd17 modified: Analyzer.C
made changes to correct for geomtry and eliminating redundant variables to a make the  code more readable
	modified:   Armory/ClassPW.h
    made changes to correct for the fact that the physical geometry of the detector is not the same as the geometry in the simulation, it is reversed and has an offset of 3
2025-02-05 08:23:23 -05:00
Vignesh Sitaraman 8d7322cf5a modified: Analyzer.C 2025-02-03 10:32:07 -05:00
Vignesh Sitaraman 699b0f8701 modified: Analyzer.C
HPZProjection implemented, testing seems to result in a plot with 0s. Need to debug
2025-01-31 09:25:37 -05:00
Vignesh Sitaraman 02213caaee modified: Analyzer.C
implementation of function to fgiure out the cqreelated cathodes in events
2025-01-28 10:19:14 -05:00
Vignesh Sitaraman 56a6389b4f modified: Analyzer.C
modified the analyser to include gain matching for the anodes and the cathodes
	modified:   FitHistogramsWithTSpectrum_Sequential_Improved.C
	modified:   MatchAndPlotCentroids.C
	modified:   centroids.txt
	modified:   slope_intercept_results.txt
2025-01-27 16:34:39 -05:00
Vignesh Sitaraman b99ad4e4d7 new file: FitHistogramsWithTSpectrum_Sequential_Improved.C
new file:   MatchAndPlotCentroids.C
	new file:   centroids.txt
	new file:   centroids_edited.txt
	new file:   slope_intercept_cathode.txt
	new file:   slope_intercept_results.txt
	new file:   slope_intercept_results_anode.txt
2025-01-27 15:11:27 -05:00
Vignesh Sitaraman a5dfa2ecd3 modified: .vscode/settings.json
modified:   Analyzer.C
	modified:   Analyzer.h
	modified:   ProcessRun.sh
2025-01-27 10:55:22 -05:00
Vignesh Sitaraman 26e943adc8 modified: .vscode/settings.json
modified:   Analyzer.C
2025-01-27 09:51:25 -05:00
vs19g 42e093b104 modified: .vscode/c_cpp_properties.json
modified:   .vscode/settings.json
	modified:   Analyzer.C
	new file:   Armory/#ClassPW.h#
	modified:   Armory/ClassDet.h
	modified:   Armory/ClassPW.h
	modified:   Armory/Mapper.cpp
2025-01-17 11:18:07 -05:00
dirac 3129339647 modified: Analyzer.C
modified:   ProcessRun.sh
	modified:   mapping.h
2024-11-05 08:48:21 -05:00
dirac 7a70340b18 modified: Analyzer.C
modified:   mapping.h
2024-10-30 09:28:01 -04:00
dirac a10081ea81 modified: .vscode/settings.json
modified:   Analyzer.C
	modified:   Analyzer.h
	modified:   Armory/ClassDet.h
	modified:   Armory/ClassPW.h
	modified:   Armory/Mapper.cpp
	modified:   PCGainMatch.C
	modified:   ProcessRun.sh
	modified:   mapping.h
2024-10-25 15:02:59 -04:00
vs19g 4cb8a2c48c new file: Analyzer1.C
new file:   Analyzer1.h
2024-10-04 12:43:24 -04:00
vs19g fe6dbee171 Refactor PCGainMatch.C and Analyzer.C for improved efficiency and readability 2024-10-01 14:13:53 -04:00
vs19g 7805481ead Refactor PCGainMatch.C and Analyzer.C for improved efficiency and readability 2024-09-16 10:25:13 -04:00
vs19g 511b4aa808 modified: PCGainMatch.C 2024-09-06 15:06:32 -04:00
vs19g 43233ceb02 modified: PCGainMatch.C 2024-09-06 14:32:22 -04:00
vs19g 68fc36a8f6 modified: PCGainMatch.C 2024-09-03 16:41:17 -04:00
vs19g a6e754b958 modified: Analyzer.C
new file:   PCGainMatch.C
	new file:   PCGainMatch.h
2024-08-28 10:49:36 -04:00
vs19g 48ede97992 modified: Analyzer.C implemented cuts and histograms for the 2D histograms 2024-08-26 11:41:06 -04:00
vs19g f0a393abe2 modified: Analyzer.C 2024-08-26 10:34:13 -04:00
vs19g 4ba9c73b98 modified: Analyzer.C 2024-08-26 10:33:29 -04:00
vs19g 238ec8961e modified: Analyzer.C 2024-08-26 10:33:29 -04:00
173 changed files with 621501 additions and 4713 deletions

32
.gitignore vendored
View File

@ -1,12 +1,40 @@
EventBuilder*
*.d *.d
*.so *.so
*.pcm *.pcm
*.root *.root
*.exe *.exe
*.txt
*.err
*.seq
*.png
*.gif
*.msh
*.vtk
Mapper Mapper
AnasenMS AnasenMS
data/ data/
data_proton/ data_proton/
Sudarshan/
wires2d/
myenv/
Analyzer_C_ACLiC_dict0713aaa966_dictContent.h
.gitignore
Analyzer_C_ACLiC_dict5411fecd5c_dictUmbrella.h
gainmatch.C
gainmatch.h
MakePlotsQQQ.C
MakePlotsQQQ.h
MakePlotsSX3.C
MakePlotsSX3.h
Armory/CorrelateQQQ.h
QQQStage2.C
anasen_fem/scalars.dat.names
anasen_fem/He96_CO2_4_260Torr.gas
anasen_fem/heavy_ion_track.csv
Armory/EventBuilder
EventBuilder
anasen_fem/anode_to_cathode_1d_17.43.csv
pc_calib_raw/
AutoFit.C
scratch/images/WedgeChVAnode.jpeg

View File

@ -1,23 +1,11 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "splitpole", "name": "Hades",
"includePath": [ "includePath": [
"${workspaceFolder}/**", "${workspaceFolder}/**",
"/home/splitpole/cern/root/**" "/usr/include/x86_64-linux-gnu/qt6/**",
], "/usr/local/cern/root_v6.26.06/include/**"
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
},
{
"name": "Ryan",
"includePath": [
"${workspaceFolder}/**",
"/home/ryan/Downloads/root_build/**",
"/home/ryan/Downloads/root_build/include"
], ],
"defines": [], "defines": [],
"compilerPath": "/usr/bin/gcc", "compilerPath": "/usr/bin/gcc",
@ -29,7 +17,8 @@
"name": "RyanUbuntu", "name": "RyanUbuntu",
"includePath": [ "includePath": [
"${workspaceFolder}/**", "${workspaceFolder}/**",
"/opt/root/**" "/usr/include/x86_64-linux-gnu/qt6/**",
"/opt/root/include/**"
], ],
"defines": [], "defines": [],
"compilerPath": "/usr/bin/gcc", "compilerPath": "/usr/bin/gcc",
@ -38,10 +27,11 @@
"intelliSenseMode": "linux-gcc-x64" "intelliSenseMode": "linux-gcc-x64"
}, },
{ {
"name": "RyanHome", "name": "Anasen",
"includePath": [ "includePath": [
"${workspaceFolder}/**", "${workspaceFolder}/**",
"/home/ryan/root_v6.30.06/**" "/usr/include/x86_64-linux-gnu/qt6/**",
"/opt/root/include/**"
], ],
"defines": [], "defines": [],
"compilerPath": "/usr/bin/gcc", "compilerPath": "/usr/bin/gcc",
@ -50,10 +40,39 @@
"intelliSenseMode": "linux-gcc-x64" "intelliSenseMode": "linux-gcc-x64"
}, },
{ {
"name": "Dirac", "name": "Splitpole",
"includePath": [ "includePath": [
"${workspaceFolder}/**", "${workspaceFolder}/**",
"/usr/opt/root/**" "/usr/include/x86_64-linux-gnu/qt6/**",
"/home/splitpole/cern/root/include/**",
"/usr/include/x86_64-linux-gnu/qt6/QtWidgets",
"/usr/include/x86_64-linux-gnu/qt6/QtCore"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
},
{
"name": "Penguin",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/x86_64-linux-gnu/qt6/**",
"/usr/local/cern/root/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
},
{
"name": "VigneshROG",
"includePath": [
"/home/vsitaraman/**",
"${workspaceFolder}/**",
"/home/vsitaraman/root/include/**"
], ],
"defines": [], "defines": [],
"compilerPath": "/usr/bin/gcc", "compilerPath": "/usr/bin/gcc",

40
.vscode/settings.json vendored
View File

@ -90,6 +90,42 @@
"processRun.C": "cpp", "processRun.C": "cpp",
"TrackRecon.C": "cpp", "TrackRecon.C": "cpp",
"processRuns.C": "cpp", "processRuns.C": "cpp",
"Analysis.C": "cpp" "Analysis.C": "cpp",
} "datastructs.h": "c",
"ANASENPlotEdit.C": "cpp",
"GetMean_Q3_new.C": "cpp",
"AlphaCal_new.C": "cpp",
"f1.C": "cpp",
"GeoCal_Maria_new.C": "cpp",
"PCPulser_All_new.C": "cpp",
"PosCal_2.C": "cpp",
"AutoFit.C": "cpp",
"Fitting.C": "cpp",
"PCGainMatch.C": "cpp",
"Analyzer1.C": "cpp",
"FitHistogramsWithTSpectrum_Sequential_Improved.C": "cpp",
"PlotAndFitCentroids.C": "cpp",
"MatchAndPlotCentroids.C": "cpp",
"GainMatch.C": "cpp",
"GainMatchSX3.C": "cpp",
"RelBack_Fix_new.C": "cpp",
"SiRelativeGains_Step1_new.C": "cpp",
"charconv": "cpp",
"format": "cpp",
"GainMatchSX3Front.C": "cpp",
"GainMatchSX3Front1.C": "cpp",
"Calibration.C": "cpp",
"GainMatchQQQ.C": "cpp",
"UTF-8gainmatch.C": "cpp",
"MakePlotsQQQ.C": "cpp",
"MakePlotsSX3.C": "cpp",
"QQQ_Calibcheck.C": "cpp",
"QQQ_Calcheck.C": "cpp",
"makeplots.C": "cpp",
"GlobalMinimizeQQQ.C": "cpp",
"QQQStage2.C": "cpp",
"inspect.C": "cpp"
},
"github-enterprise.uri": "https://fsunuc.physics.fsu.edu",
"C_Cpp.default.compilerPath": "/usr/bin/gcc"
} }

View File

@ -1,20 +0,0 @@
#include "TChain.h"
#include <iostream>
void Analysis(int start, int end) {
// Create a TChain
TChain *chain = new TChain("tree");
for(int i = start; i < end+1; i++) {
chain->Add(Form("data/root_data/Run_%03d_mapped.root", i));
}
// Process the chain using Analyzer.C+
chain->Process("Analyzer.C+");
}
// Define a macro with the same name as the script
void Analysis() {
Analysis(72, 194); // Adjust the range if needed
}

View File

@ -42,7 +42,7 @@ void ANASEN_model(int anodeID1 = -1, int anodeID2 = -1, int cathodeID1 = -1, int
//--- making ANASEN //--- making ANASEN
const int nWire = 24; const int nWire = 24;
const int wireShift = 3; const int wireShift = 3;
const int zLen = 300; //mm const int zLen = 350; //mm
const int radiusA = 38; const int radiusA = 38;
const int radiusC = 43; const int radiusC = 43;
@ -103,8 +103,8 @@ void ANASEN_model(int anodeID1 = -1, int anodeID2 = -1, int cathodeID1 = -1, int
new TGeoRotation("rot1", 360/nSX3 * (i + 0.5), 0., 0.))); new TGeoRotation("rot1", 360/nSX3 * (i + 0.5), 0., 0.)));
} }
const int qqqR1 = 10; const int qqqR1 = 50;
const int qqqR2 = 50; const int qqqR2 = 100;
TGeoVolume *qqq = geom->MakeTubs("qqq", Al, qqqR1, qqqR2, 0.5, 5, 85); TGeoVolume *qqq = geom->MakeTubs("qqq", Al, qqqR1, qqqR2, 0.5, 5, 85);
qqq->SetLineColor(7); qqq->SetLineColor(7);
for( int i = 0; i < 4; i++){ for( int i = 0; i < 4; i++){

1270
Armory/ClassData.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,60 +5,67 @@
#define MAXMULTI 1000 #define MAXMULTI 1000
class Det{ class Det
{
public: public:
Det(): multi(0) {Clear(); } Det() : multi(0) { Clear(); }
unsigned short multi; // max 65535 unsigned short multi; // max 65535
unsigned short id[MAXMULTI]; unsigned short id[MAXMULTI];
unsigned short ch[MAXMULTI]; unsigned short ch[MAXMULTI];
unsigned short e[MAXMULTI]; unsigned short e[MAXMULTI];
unsigned long long t[MAXMULTI]; unsigned long long t[MAXMULTI];
unsigned long long tf[MAXMULTI];
unsigned short sn[MAXMULTI]; unsigned short sn[MAXMULTI];
unsigned short digiCh[MAXMULTI]; unsigned short digiCh[MAXMULTI];
unsigned short index[MAXMULTI]; // id * nCh + ch; unsigned short index[MAXMULTI]; // id * nCh + ch;
bool used[MAXMULTI]; bool used[MAXMULTI];
void Clear(){ void Clear()
{
multi = 0; multi = 0;
for( int i = 0; i < MAXMULTI; i++){ for (int i = 0; i < MAXMULTI; i++)
{
id[i] = 0; id[i] = 0;
ch[i] = 0; ch[i] = 0;
e[i] = 0; e[i] = 0;
t[i] = 0; t[i] = 0;
index[i] = 0; tf[i] = 0;
sn[i] = 0; index[i] = 0;
digiCh[i] = 0; sn[i] = 0;
used[i] = false; digiCh[i] = 0;
used[i] = false;
} }
} }
void Print(){ void Print()
{
printf("=============================== multi : %u\n", multi); printf("=============================== multi : %u\n", multi);
for( int i = 0; i < multi; i++) { for (int i = 0; i < multi; i++)
printf(" %3d | %2d-%-2d(%5d) %5u %15llu \n", i, id[i], ch[i], index[i], e[i], t[i]); {
printf(" %3d | %2d-%-2d(%5d) %5u %15llu %15llu \n", i, id[i], ch[i], index[i], e[i], t[i], tf[i]);
} }
} }
void SetDetDimension(unsigned short maxID, unsigned maxCh){ void SetDetDimension(unsigned short maxID, unsigned maxCh)
{
nID = maxID; nID = maxID;
nCh = maxCh; nCh = maxCh;
} }
void CalIndex(){ void CalIndex()
for( int i = 0; i < multi; i++){ {
index[i] = id[i] * nCh + ch[i] ; for (int i = 0; i < multi; i++)
{
index[i] = id[i] * nCh + ch[i];
} }
} }
private: private:
unsigned short nID; unsigned short nID;
unsigned short nCh; unsigned short nCh;
}; };
#endif #endif

View File

@ -1,246 +0,0 @@
#ifndef ClassPC_h
#define ClassPC_h
#include <cstdio>
#include <TMath.h>
#include <TVector3.h>
#include <TRandom.h>
struct PCHit_1An{
std::pair<short, short> nearestWire; // anode, cathode
std::pair<double, double> nearestDist; // anode, cathode
short nextNearestWire; // cathode
double nextNearestDist; // cathode
void Clear(){
nearestWire.first = -1;
nearestWire.second = -1;
nearestDist.first = 999999999;
nearestDist.second = 999999999;
nextNearestWire= -1;
nextNearestDist = 999999999;
}
};
//!########################################################
class PC{ // proportional wire
public:
PC(){ ClearHitInfo();};
~PC(){};
PCHit_1An GetHitInfo() const {return hitInfo;}
std::pair<short, short> GetNearestID() const {return hitInfo.nearestWire;}
std::pair<double, double> GetNearestDistance() const {return hitInfo.nearestDist;}
short Get2ndNearestID() const {return hitInfo.nextNearestWire;}
double Get2ndNearestDistance() const {return hitInfo.nextNearestDist;}
TVector3 GetTrackPos() const {return trackPos;}
TVector3 GetTrackVec() const {return trackVec;}
double GetTrackTheta() const {return trackVec.Theta();}
double GetTrackPhi() const {return trackVec.Phi();}
double GetZ0();
int GetNumWire() const {return nWire;}
double GetDeltaAngle() const {return dAngle;}
double GetAnodeLength() const {return anodeLength;}
double GetCathodeLength() const {return cathodeLength;}
TVector3 GetAnodeDn(short id) const {return An[id].first;}
TVector3 GetAnodeUp(short id) const {return An[id].second;}
TVector3 GetCathodeDn(short id) const {return Ca[id].first;}
TVector3 GetCathodeUp(short id) const {return Ca[id].second;}
TVector3 GetAnodneMid(short id) const {return (An[id].first + An[id].second) * 0.5; }
double GetAnodeTheta(short id) const {return (An[id].first - An[id].second).Theta();}
double GetAnodePhi(short id) const {return (An[id].first - An[id].second).Phi();}
TVector3 GetCathodneMid(short id) const {return (Ca[id].first + Ca[id].second) * 0.5; }
double GetCathodeTheta(short id) const {return (Ca[id].first - Ca[id].second).Theta();}
double GetCathodePhi(short id) const {return (Ca[id].first - Ca[id].second).Phi();}
void ClearHitInfo();
void ConstructGeo();
void FindWireID(TVector3 pos, TVector3 direction, bool verbose = false);
void CalTrack3(TVector3 sx3Pos, PCHit_1An hitInfo, double sigmaA = 0, double sigmaC = 0, bool verbose = false);
void Print(){
printf(" The nearest | Anode: %2d(%5.2f) Cathode: %2d(%5.2f)\n", hitInfo.nearestWire.first,
hitInfo.nearestDist.first,
hitInfo.nearestWire.second,
hitInfo.nearestDist.second);
printf(" The 2nd nearest Cathode: %2d(%5.2f)\n", hitInfo.nextNearestWire,
hitInfo.nextNearestDist);
}
private:
// PCHitInfo hitInfo;
PCHit_1An hitInfo;
TVector3 trackPos;
TVector3 trackVec;
const int nWire = 24;
const int wireShift = 3;
const float zLen = 380; //mm
const float radiusA = 37;
const float radiusC = 43;
double dAngle;
double anodeLength;
double cathodeLength;
std::vector<std::pair<TVector3,TVector3>> An; // the anode wire position vector in space
std::vector<std::pair<TVector3,TVector3>> Ca; // the cathode wire position vector in space
double Distance(TVector3 a1, TVector3 a2, TVector3 b1, TVector3 b2){
TVector3 na = a1 - a2;
TVector3 nb = b1 - b2;
TVector3 nd = (na.Cross(nb)).Unit();
return TMath::Abs(nd.Dot(a1-b2));
}
};
inline void PC::ClearHitInfo(){
hitInfo.Clear();
}
inline void PC::ConstructGeo(){
An.clear();
Ca.clear();
std::pair<TVector3, TVector3> p1; // anode
std::pair<TVector3, TVector3> q1; // cathode
//anode and cathode start at pos-Y axis and count in right-Hand
//anode wire shift is right-hand.
//cathode wire shift is left-hand.
for(int i = 0; i < nWire; i++ ){
// Anode rotate right-hand
p1.first.SetXYZ( radiusA * TMath::Cos( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()),
radiusA * TMath::Sin( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()),
zLen/2);
p1.second.SetXYZ( radiusA * TMath::Cos( TMath::TwoPi() / nWire * (i + wireShift) + TMath::PiOver2()),
radiusA * TMath::Sin( TMath::TwoPi() / nWire * (i + wireShift) + TMath::PiOver2()),
-zLen/2);
An.push_back(p1);
// Cathod rotate left-hand
q1.first.SetXYZ( radiusC * TMath::Cos( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()),
radiusC * TMath::Sin( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()),
zLen/2);
q1.second.SetXYZ( radiusC * TMath::Cos( TMath::TwoPi() / nWire * (i - wireShift) + TMath::PiOver2()),
radiusC * TMath::Sin( TMath::TwoPi() / nWire * (i - wireShift) + TMath::PiOver2()),
-zLen/2);
Ca.push_back(q1);
}
dAngle = wireShift * TMath::TwoPi() / nWire;
anodeLength = TMath::Sqrt( zLen*zLen + TMath::Power(2* radiusA * TMath::Sin(dAngle/2),2) );
cathodeLength = TMath::Sqrt( zLen*zLen + TMath::Power(2* radiusC * TMath::Sin(dAngle/2),2) );
}
inline void PC::FindWireID(TVector3 pos, TVector3 direction, bool verbose ){
hitInfo.Clear();
double phi = direction.Phi();
for( int i = 0; i < nWire; i++){
double disA = 99999999;
double phiS = An[i].first.Phi() - TMath::PiOver4();
double phiL = An[i].second.Phi() + TMath::PiOver4();
// printf("A%2d: %f %f | %f\n", i, phiS * TMath::RadToDeg(), phiL * TMath::RadToDeg(), phi * TMath::RadToDeg());
if( phi > 0 && phiS > phiL ) phiL = phiL + TMath::TwoPi();
if( phi < 0 && phiS > phiL ) phiS = phiS - TMath::TwoPi();
if( phiS < phi && phi < phiL) {
disA = Distance( pos, pos + direction, An[i].first, An[i].second);
if( disA < hitInfo.nearestDist.first ){
hitInfo.nearestDist.first = disA;
hitInfo.nearestWire.first = i;
}
}
double disC = 99999999;
phiS = Ca[i].second.Phi()- TMath::PiOver4();
phiL = Ca[i].first.Phi() + TMath::PiOver4();
// printf("C%2d: %f %f\n", i, phiS * TMath::RadToDeg(), phiL * TMath::RadToDeg());
if( phi > 0 && phiS > phiL ) phiL = phiL + TMath::TwoPi();
if( phi < 0 && phiS > phiL ) phiS = phiS - TMath::TwoPi();
if(phiS < phi && phi < phiL) {
disC = Distance( pos, pos + direction, Ca[i].first, Ca[i].second);
if( disC < hitInfo.nearestDist.second ){
hitInfo.nearestDist.second = disC;
hitInfo.nearestWire.second = i;
}
}
if(verbose) printf(" %2d | %8.2f, %8.2f\n", i, disA, disC);
}
short cathode1 = hitInfo.nearestWire.second;
short ccc1 = cathode1 - 1; if( ccc1 < 0 ) ccc1 += nWire;
short ccc2 = (cathode1 + 1) % nWire;
double haha1 = Distance( pos, pos + direction, Ca[ccc1].first, Ca[ccc1].second);
double haha2 = Distance( pos, pos + direction, Ca[ccc2].first, Ca[ccc2].second);
if( haha1 < haha2){
hitInfo.nextNearestWire = ccc1;
hitInfo.nextNearestDist = haha1;
}else{
hitInfo.nextNearestWire = ccc2;
hitInfo.nextNearestDist= haha2;
}
if( verbose ) Print();
}
inline void PC::CalTrack3(TVector3 sx3Pos, PCHit_1An hitInfo, double sigmaA, double sigmaC, bool verbose){
trackPos = sx3Pos;
double p1 = TMath::Abs(hitInfo.nearestDist.first + gRandom->Gaus(0, sigmaA));
short anodeID1 = hitInfo.nearestWire.first;
double q1 = TMath::Abs(hitInfo.nearestDist.second + gRandom->Gaus(0, sigmaC));
double q2 = TMath::Abs(hitInfo.nextNearestDist+ gRandom->Gaus(0, sigmaC));
double fracC = q1 / (q1 + q2);
short cathodeID1 = hitInfo.nearestWire.second;
short cathodeID2 = hitInfo.nextNearestWire;
TVector3 shiftC1 = (Ca[cathodeID2].first - Ca[cathodeID1].first) * fracC;
TVector3 shiftC2 = (Ca[cathodeID2].second - Ca[cathodeID1].second) * fracC;
TVector3 a1 = An[anodeID1].first;
TVector3 c1 = Ca[cathodeID1].first + shiftC1;
TVector3 c2 = Ca[cathodeID1].second + shiftC2;
TVector3 n1 = (sx3Pos - a1).Unit();
TVector3 n2 = (c1 - c2).Cross((sx3Pos - c2)).Unit();
// if the handiness of anode and cathode revered, it should be n2 cross n1
trackVec = (n2.Cross(n1)).Unit();
if( verbose ) printf("Theta, Phi = %f, %f \n", trackVec.Theta() *TMath::RadToDeg(), trackVec.Phi()*TMath::RadToDeg());
}
inline double PC::GetZ0(){
double x = trackPos.X();
double y = trackPos.Y();
double rho = TMath::Sqrt(x*x + y*y);
double theta = trackVec.Theta();
return trackPos.Z() - rho / TMath::Tan(theta);
}
#endif

688
Armory/ClassPW.h Normal file → Executable file
View File

@ -2,17 +2,21 @@
#define ClassPW_h #define ClassPW_h
#include <cstdio> #include <cstdio>
#include <iostream>
#include <TMath.h> #include <TMath.h>
#include <TVector3.h> #include <TVector3.h>
#include <TRandom.h>
struct PWHitInfo{ struct PWHitInfo
std::pair<short, short> nearestWire; // anode, cathode {
std::pair<short, short> nearestWire; // anode, cathode
std::pair<double, double> nearestDist; // anode, cathode std::pair<double, double> nearestDist; // anode, cathode
std::pair<short, short> nextNearestWire; // anode, cathode std::pair<short, short> nextNearestWire; // anode, cathode
std::pair<double, double> nextNearestDist; // anode, cathode std::pair<double, double> nextNearestDist; // anode, cathode
void Clear(){ void Clear()
{
nearestWire.first = -1; nearestWire.first = -1;
nearestWire.second = -1; nearestWire.second = -1;
nearestDist.first = 999999999; nearestDist.first = 999999999;
@ -24,95 +28,125 @@ struct PWHitInfo{
} }
}; };
//!######################################################## struct Coord
class PW{ // proportional wire {
float x, y, z;
Coord() : x(0), y(0), z(0) {}
Coord(const TVector3 &vec)
{
x = vec.X(); // TVector3's X() returns the x-coordinate
y = vec.Y(); // TVector3's Y() returns the y-coordinate
z = vec.Z(); // TVector3's Z() returns the z-coordinate
}
};
//! ########################################################
class PW
{ // proportional wire
public: public:
PW(){ ClearHitInfo();}; PW() { ClearHitInfo(); };
~PW(){}; ~PW() {};
PWHitInfo GetHitInfo() const {return hitInfo;} PWHitInfo GetHitInfo() const { return hitInfo; }
std::pair<short, short> GetNearestID() const {return hitInfo.nearestWire;} std::pair<short, short> GetNearestID() const { return hitInfo.nearestWire; }
std::pair<double, double> GetNearestDistance() const {return hitInfo.nearestDist;} std::pair<double, double> GetNearestDistance() const { return hitInfo.nearestDist; }
std::pair<short, short> Get2ndNearestID() const {return hitInfo.nextNearestWire;} std::pair<short, short> Get2ndNearestID() const { return hitInfo.nextNearestWire; }
std::pair<double, double> Get2ndNearestDistance() const {return hitInfo.nextNearestDist;} std::pair<double, double> Get2ndNearestDistance() const { return hitInfo.nextNearestDist; }
TVector3 GetTrackPos() const {return trackPos;} std::vector<std::pair<TVector3, TVector3>> An; // the anode wire position vector in space
TVector3 GetTrackVec() const {return trackVec;} std::vector<std::pair<TVector3, TVector3>> Ca; // the cathode wire position vector in space
double GetTrackTheta() const {return trackVec.Theta();}
double GetTrackPhi() const {return trackVec.Phi();} TVector3 GetTrackPos() const { return trackPos; }
TVector3 GetTrackVec() const { return trackVec; }
double GetTrackTheta() const { return trackVec.Theta(); }
double GetTrackPhi() const { return trackVec.Phi(); }
double GetZ0(); double GetZ0();
int GetNumWire() const {return nWire;} Coord Crossover[24][24][2];
double GetDeltaAngle() const {return dAngle;}
double GetAnodeLength() const {return anodeLength;}
double GetCathodeLength() const {return cathodeLength;}
TVector3 GetAnodeDn(short id) const {return An[id].first;}
TVector3 GetAnodeUp(short id) const {return An[id].second;}
TVector3 GetCathodeDn(short id) const {return Ca[id].first;}
TVector3 GetCathodeUp(short id) const {return Ca[id].second;}
TVector3 GetAnodneMid(short id) const {return (An[id].first + An[id].second) * 0.5; } inline TVector3 getClosestWirePosAtWirePhi(std::pair<TVector3, TVector3>, double phi);
double GetAnodeTheta(short id) const {return (An[id].first - An[id].second).Theta();} inline TVector3 getClosestWirePosAtWirePhiOld(std::pair<TVector3, TVector3>, double phi);
double GetAnodePhi(short id) const {return (An[id].first - An[id].second).Phi();} inline std::tuple<std::pair<TVector3, TVector3>, double, double, double> GetPseudoWire(const std::vector<std::tuple<int, double, double>> &cluster, std::string type);
TVector3 GetCathodneMid(short id) const {return (Ca[id].first + Ca[id].second) * 0.5; } inline std::tuple<TVector3, double, double, double, double, double, double, double>
double GetCathodeTheta(short id) const {return (Ca[id].first - Ca[id].second).Theta();} FindCrossoverProperties(const std::vector<std::tuple<int, double, double>> &a_cluster, const std::vector<std::tuple<int, double, double>> &c_cluster);
double GetCathodePhi(short id) const {return (Ca[id].first - Ca[id].second).Phi();}
inline std::vector<std::vector<std::tuple<int, double, double>>>
Make_Clusters(const std::unordered_map<int, std::tuple<int, double, double>> &wireEvents);
int GetNumWire() const { return nWire; }
double GetDeltaAngle() const { return dAngle; }
double GetAnodeLength() const { return anodeLength; }
double GetCathodeLength() const { return cathodeLength; }
TVector3 GetAnodeDn(short id) const { return An[id].first; }
TVector3 GetAnodeUp(short id) const { return An[id].second; }
TVector3 GetCathodeDn(short id) const { return Ca[id].first; }
TVector3 GetCathodeUp(short id) const { return Ca[id].second; }
TVector3 GetAnodneMid(short id) const { return (An[id].first + An[id].second) * 0.5; }
double GetAnodeTheta(short id) const { return (An[id].first - An[id].second).Theta(); }
double GetAnodePhi(short id) const { return (An[id].first - An[id].second).Phi(); }
TVector3 GetCathodeMid(short id) const { return (Ca[id].first + Ca[id].second) * 0.5; }
double GetCathodeTheta(short id) const { return (Ca[id].first - Ca[id].second).Theta(); }
double GetCathodePhi(short id) const { return (Ca[id].first - Ca[id].second).Phi(); }
void ClearHitInfo(); void ClearHitInfo();
void ConstructGeo(); void ConstructGeo();
void FindWireID(TVector3 pos, TVector3 direction, bool verbose = false); void FindWireID(TVector3 pos, TVector3 direction, bool verbose = false);
void CalTrack(TVector3 sx3Pos, int anodeID, int cathodeID, bool verbose = false); void CalTrack(TVector3 sx3Pos, int anodeID, int cathodeID, bool verbose = false);
void CalTrack2(TVector3 sx3Pos, PWHitInfo hitInfo, double sigmaA = 0, double sigmaC = 0, bool verbose = false); void CalTrack2(TVector3 sx3Pos, TVector3 anodeInt, bool verbose = false);
double CircularMean(std::vector<std::pair<int, double>> wireList); void Print()
{
void Print(){
printf(" The nearest | Anode: %2d(%5.2f) Cathode: %2d(%5.2f)\n", hitInfo.nearestWire.first, printf(" The nearest | Anode: %2d(%5.2f) Cathode: %2d(%5.2f)\n", hitInfo.nearestWire.first,
hitInfo.nearestDist.first, hitInfo.nearestDist.first,
hitInfo.nearestWire.second, hitInfo.nearestWire.second,
hitInfo.nearestDist.second); hitInfo.nearestDist.second);
printf(" The 2nd nearest | Anode: %2d(%5.2f) Cathode: %2d(%5.2f)\n", hitInfo.nextNearestWire.first, printf(" The 2nd nearest | Anode: %2d(%5.2f) Cathode: %2d(%5.2f)\n", hitInfo.nextNearestWire.first,
hitInfo.nextNearestDist.first, hitInfo.nextNearestDist.first,
hitInfo.nextNearestWire.second, hitInfo.nextNearestWire.second,
hitInfo.nextNearestDist.second); hitInfo.nextNearestDist.second);
} }
private: private:
PWHitInfo hitInfo; PWHitInfo hitInfo;
TVector3 trackPos; TVector3 trackPos;
TVector3 trackVec; TVector3 trackVec;
const int nWire = 24; const int nWire = 24;
const int wireShift = 3; const int wireShift = 4;
const float zLen = 380; //mm // const float zLen = 380; // mm
// const float zLen = 348.6; // mm
const float zLen = 174.3 * 2; // mm
const float radiusA = 37; const float radiusA = 37;
const float radiusC = 43; const float radiusC = 42;
double dAngle; double dAngle;
double anodeLength; double anodeLength;
double cathodeLength; double cathodeLength;
std::vector<std::pair<TVector3,TVector3>> An; // the anode wire position vector in space // std::vector<std::pair<TVector3, TVector3>> An; // the anode wire position vector in space
std::vector<std::pair<TVector3,TVector3>> Ca; // the cathode wire position vector in space // std::vector<std::pair<TVector3, TVector3>> Ca; // the cathode wire position vector in space
double Distance(TVector3 a1, TVector3 a2, TVector3 b1, TVector3 b2){ double Distance(TVector3 a1, TVector3 a2, TVector3 b1, TVector3 b2)
{
TVector3 na = a1 - a2; TVector3 na = a1 - a2;
TVector3 nb = b1 - b2; TVector3 nb = b1 - b2;
TVector3 nd = (na.Cross(nb)).Unit(); TVector3 nd = (na.Cross(nb)).Unit();
return TMath::Abs(nd.Dot(a1-b2)); return TMath::Abs(nd.Dot(a1 - b2));
} }
}; };
inline void PW::ClearHitInfo(){ inline void PW::ClearHitInfo()
{
hitInfo.Clear(); hitInfo.Clear();
} }
inline void PW::ConstructGeo(){ inline void PW::ConstructGeo()
{
An.clear(); An.clear();
Ca.clear(); Ca.clear();
@ -120,108 +154,416 @@ inline void PW::ConstructGeo(){
std::pair<TVector3, TVector3> p1; // anode std::pair<TVector3, TVector3> p1; // anode
std::pair<TVector3, TVector3> q1; // cathode std::pair<TVector3, TVector3> q1; // cathode
//anode and cathode start at pos-Y axis and count in right-Hand double k = TMath::TwoPi() / 24.; // 48 solder thru holes, wires in every other one
//anode wire shift is right-hand. double offset_a1 = -6 * k - 4 * k; // -6 to go from 0,0 to 90degree up, and 4 for the wire offset //old version -5 * k - 5 * k;
//cathode wire shift is left-hand. double offset_c1 = -6 * k + k / 2.0; // correct for a half-turn
// std::cerr << "Here!" << std::endl;
// #include "../scratch/testing.h"
double offset_a2 = offset_a1 + wireShift * k;
double offset_c2 = offset_c1 - wireShift * k;
for(int i = 0; i < nWire; i++ ){ for (int i = 0; i < nWire; i++)
// Anode rotate right-hand {
p1.first.SetXYZ( radiusA * TMath::Cos( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()), // Anode rotate right-hand coming in towards +z riding with the beam. In this frame, +x is to the right, and +y down
radiusA * TMath::Sin( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()), // updated Feb 2026, Sudarsan B. Photographs indicate that anode wires twist right handed, as one moves from -z to +z with the convention above
zLen/2); // wire indices increase leftward as one moves to +z (hence -k factor), but wires themselves twist rightward - as indicated by offset_a2 being more +ve w.r.t offset_a1
p1.second.SetXYZ( radiusA * TMath::Cos( TMath::TwoPi() / nWire * (i + wireShift) + TMath::PiOver2()), //'First' is -z locus, 'second' is +z locus
radiusA * TMath::Sin( TMath::TwoPi() / nWire * (i + wireShift) + TMath::PiOver2()), p1.first.SetXYZ(radiusA * TMath::Cos(-k * i + offset_a1),
-zLen/2); radiusA * TMath::Sin(-k * i + offset_a1),
-zLen / 2);
p1.second.SetXYZ(radiusA * TMath::Cos(-k * i + offset_a2),
radiusA * TMath::Sin(-k * i + offset_a2),
+zLen / 2);
// Cathodes twist left-hand as indicated by offset_c2 being more negative than offset_c1, under the same system, while wires increase rightward (hence +k factor)
q1.first.SetXYZ(radiusC * TMath::Cos(k * i + offset_c1),
radiusC * TMath::Sin(k * i + offset_c1),
-zLen / 2);
q1.second.SetXYZ(radiusC * TMath::Cos(k * i + offset_c2),
radiusC * TMath::Sin(k * i + offset_c2),
zLen / 2);
An.push_back(p1); An.push_back(p1);
// Cathod rotate left-hand
q1.first.SetXYZ( radiusC * TMath::Cos( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()),
radiusC * TMath::Sin( TMath::TwoPi() / nWire * (i) + TMath::PiOver2()),
zLen/2);
q1.second.SetXYZ( radiusC * TMath::Cos( TMath::TwoPi() / nWire * (i - wireShift) + TMath::PiOver2()),
radiusC * TMath::Sin( TMath::TwoPi() / nWire * (i - wireShift) + TMath::PiOver2()),
-zLen/2);
Ca.push_back(q1); Ca.push_back(q1);
} }
// Calculate Crossover Geometry ONCE
TVector3 a, c, diff;
double a2, ac, c2, adiff, cdiff, denom, alpha;
for (size_t i = 0; i < An.size(); i++)
{
// a = An[i].first - An[i].second;
a = An[i].second - An[i].first;
for (size_t j = 0; j < Ca.size(); j++)
{
c = Ca[j].second - Ca[j].first;
diff = An[i].second - Ca[j].second;
a2 = a.Dot(a);
c2 = c.Dot(c);
ac = a.Dot(c);
adiff = a.Dot(diff);
cdiff = c.Dot(diff);
denom = a2 * c2 - ac * ac;
alpha = (ac * cdiff - c2 * adiff) / denom;
Crossover[i][j][0].x = An[i].second.X() + alpha * a.X();
Crossover[i][j][0].y = An[i].second.Y() + alpha * a.Y();
Crossover[i][j][0].z = An[i].second.Z() + alpha * a.Z();
if (Crossover[i][j][0].z < -190 || Crossover[i][j][0].z > 190)
{
// std::cout << "Weird crossover but ok" << std::endl;
}
if ((i + j) % 24 == 12 || Crossover[i][j][0].z < -190 || Crossover[i][j][0].z > 190)
{
Crossover[i][j][0].z = 9999999;
// std::cout << "Weird crossover" << std::endl;
}
Crossover[i][j][1].x = alpha;
Crossover[i][j][1].y = 0;
}
}
dAngle = wireShift * TMath::TwoPi() / nWire; dAngle = wireShift * TMath::TwoPi() / nWire;
anodeLength = TMath::Sqrt( zLen*zLen + TMath::Power(2* radiusA * TMath::Sin(dAngle/2),2) ); anodeLength = TMath::Sqrt(zLen * zLen + TMath::Power(2 * radiusA * TMath::Sin(dAngle / 2), 2));
cathodeLength = TMath::Sqrt( zLen*zLen + TMath::Power(2* radiusC * TMath::Sin(dAngle/2),2) ); cathodeLength = TMath::Sqrt(zLen * zLen + TMath::Power(2 * radiusC * TMath::Sin(dAngle / 2), 2)); // chord length subtending an angle alpha is 2rsin(alpha/2)
} }
inline void PW::FindWireID(TVector3 pos, TVector3 direction, bool verbose ){ inline TVector3 PW::getClosestWirePosAtWirePhiOld(std::pair<TVector3, TVector3> awire, double sx3phi_radian)
{
// 1. Get wire geometry
TVector3 a1 = awire.first; // Top of the wire
TVector3 a2 = awire.second; // Bottom of the wire
TVector3 wireVec = a2 - a1; // Vector pointing down the wire
// Variables to track our minimums during the scan
double min_delta_phi = 9999.0;
double best_t = -1.0;
TVector3 best_pcz_intersect;
// 2. THE SCAN: Walk down the wire in 1000 tiny steps
// (For a 380mm wire, this is checking every 0.38 mm)
int num_steps = 1000;
for (int i = 0; i <= num_steps; ++i)
{
double t_test = (double)i / num_steps; // Ranges from 0.0 to 1.0
TVector3 test_pt = a1 + t_test * wireVec; // The 3D point at this step
// Calculate absolute Delta Phi between Si hit and this specific point on the wire
if (TMath::IsNaN(sx3phi_radian - test_pt.Phi()))
continue;
double dPhi = TMath::Abs(TVector2::Phi_mpi_pi(sx3phi_radian - test_pt.Phi())); // Phi_mpi_pi just puts the angle in the range -180 to 180
// If this is the smallest Delta Phi we've seen so far, save it!
if (dPhi < min_delta_phi)
{
min_delta_phi = dPhi;
best_t = t_test;
best_pcz_intersect = test_pt;
}
}
return best_pcz_intersect;
}
inline TVector3 PW::getClosestWirePosAtWirePhi(std::pair<TVector3, TVector3> awire, double phi)
{
const TVector3 &a1 = awire.first;
const TVector3 &a2 = awire.second;
const double s = TMath::Sin(phi), c = TMath::Cos(phi);
const double dx = a2.X() - a1.X(), dy = a2.Y() - a1.Y();
const double t = (a1.Y() * c - a1.X() * s) / (dx * s - dy * c);
auto nearerEndpoint = [&]() -> TVector3
{
auto dphi = [&](const TVector3 &p)
{
return TMath::Abs(TVector2::Phi_mpi_pi(phi - p.Phi()));
};
return dphi(a1) <= dphi(a2) ? a1 : a2;
};
if (t < 0.0 || t > 1.0)
return nearerEndpoint();
const TVector3 hit = a1 + t * (a2 - a1);
if (hit.X() * c + hit.Y() * s <= 0.0) // wrong half-plane (anti-phi side)
return nearerEndpoint();
return hit;
}
inline std::vector<std::vector<std::tuple<int, double, double>>>
PW::Make_Clusters(const std::unordered_map<int, std::tuple<int, double, double>> &wireEvents)
{
std::vector<std::vector<std::tuple<int, double, double>>> wireClusters;
std::vector<std::tuple<int, double, double>> wireCluster;
// TODO: Write a macro once, call it twice
int wirecount = 0;
while (wirecount < 24)
{
if (wireEvents.find(wirecount) == wireEvents.end())
{
wirecount++;
continue;
}
wireCluster.clear();
int ctr2 = wirecount;
do
{
wireCluster.emplace_back(wireEvents.at(ctr2));
ctr2 += 1;
if (ctr2 == 24 || ctr2 - wirecount == 7)
break; // loose logic, needs to be looked at.
} while (wireEvents.find(ctr2) != wireEvents.end());
wireClusters.push_back(std::move(wireCluster));
wirecount = ctr2; // we already dealt with wires until the last value of ctr2
}
if (wireClusters.size() > 1)
{ // Deal with wraparound if required
auto first_cluster = wireClusters.front(); // front and back provide references to the elements themselves. less copy, can modify etc
auto last_cluster = wireClusters.back();
if (std::get<0>(last_cluster.back()) == 23 && std::get<0>(first_cluster.front()) == 0)
{
last_cluster.insert(last_cluster.end(), first_cluster.begin(), first_cluster.end());
}
wireClusters.erase(wireClusters.begin()); // canonically, erase() needs an iterator, hence begin() not front()
// TODO: Can also deal with 'gaps' of missing wires similarly. end of one segment and beginning of another segment will be separated by missing wire --> combine the two
// TODO: Also needs some development regarding the time-correlation. Don't put wires in the same cluster if they aren't time coincident
}
return wireClusters;
/*if(aClusters.size()>1 || cClusters.size() > 1) {
std::cout << " ============== " << std::endl;
}
if(aClusters.size()>1 && cClusters.size() >=1) {
std::cout << aClusters.size() << " new anode clusters ----> " << std::endl;
int cc=1;
for(auto ac : aClusters) {
std::cout << " Cluster " << cc << std::endl;
double first_ts = std::get<2>(ac.at(0));
for(auto item : ac) {
std::cout << " \t" << std::get<0>(item) << " " << std::get<1>(item) << " " << std::get<2>(item)-first_ts << std::endl;
}
std::cout << " ------" << std::endl;
cc++;
}
}
if(cClusters.size()>=1 ) {
std::cout << cClusters.size() << " new cathode clusters ----> " << std::endl;
int cc=1;
for(auto ac : cClusters) {
std::cout << " Cluster " << cc << std::endl;
double first_ts = std::get<2>(ac.at(0));
for(auto item : ac) {
std::cout << " \t" << std::get<0>(item) << " " << std::get<1>(item) << " " << std::get<2>(item)-first_ts << std::endl;
}
std::cout << " ------" << std::endl;
cc++;
}
} */
}
inline std::tuple<std::pair<TVector3, TVector3>, double, double, double>
PW::GetPseudoWire(const std::vector<std::tuple<int, double, double>> &cluster, std::string type)
{
std::pair<TVector3, TVector3> avgvec = std::pair(TVector3(0, 0, 0), TVector3(0, 0, 0));
double sumEnergy = 0;
double maxEnergy = 0;
double tsMaxEnergy = 0;
if (type == "ANODE")
{
// if(cluster.size()>1) std::cout << " -------anodes" << std::endl;
for (auto wire : cluster)
{
avgvec.first += std::get<1>(wire) * TVector3(An.at(std::get<0>(wire)).first.X(), An.at(std::get<0>(wire)).first.Y(), 0);
avgvec.second += std::get<1>(wire) * TVector3(An.at(std::get<0>(wire)).second.X(), An.at(std::get<0>(wire)).second.Y(), 0);
sumEnergy += std::get<1>(wire);
if (std::get<1>(wire) > maxEnergy)
{
maxEnergy = std::get<1>(wire);
tsMaxEnergy = std::get<2>(wire);
}
/*if(cluster.size()>1) {
std::cout << "\t\t ch:" << std::get<0>(wire) << " " << std::get<1>(wire) << " " << std::get<2>(wire) << std::endl;
std::cout << "\t\t w1(r,phi,z):" << An.at(std::get<0>(wire)).first.Perp() << " " << An.at(std::get<0>(wire)).first.Phi()*180/M_PI << " " << An.at(std::get<0>(wire)).first.Z() << std::endl;
std::cout << "\t\t w2(r,phi,z):" << An.at(std::get<0>(wire)).second.Perp() << " " << An.at(std::get<0>(wire)).second.Phi()*180/M_PI << " " << An.at(std::get<0>(wire)).second.Z() << std::endl;
}*/
}
avgvec.first = avgvec.first * (1.0 / sumEnergy);
avgvec.second = avgvec.second * (1.0 / sumEnergy);
double phi1 = avgvec.first.Phi();
double phi2 = avgvec.second.Phi();
avgvec.first.SetXYZ(radiusA * TMath::Cos(phi1), radiusA * TMath::Sin(phi1), -zLen / 2);
avgvec.second.SetXYZ(radiusA * TMath::Cos(phi2), radiusA * TMath::Sin(phi2), zLen / 2);
/*if(cluster.size()>1) {
std::cout << "\t\t avg1(r,phi,z):" << avgvec.first.Perp() << " " << avgvec.first.Phi()*180/M_PI << " " << avgvec.first.Z() << std::endl;
std::cout << "\t\t avg2(r,phi,z):" << avgvec.second.Perp() << " " << avgvec.second.Phi()*180/M_PI << " " << avgvec.second.Z() << std::endl;
}*/
}
else if (type == "CATHODE")
{
for (auto wire : cluster)
{
avgvec.first += std::get<1>(wire) * TVector3(Ca.at(std::get<0>(wire)).first.X(), Ca.at(std::get<0>(wire)).first.Y(), 0);
avgvec.second += std::get<1>(wire) * TVector3(Ca.at(std::get<0>(wire)).second.X(), Ca.at(std::get<0>(wire)).second.Y(), 0);
sumEnergy += std::get<1>(wire);
if (std::get<1>(wire) > maxEnergy)
{
maxEnergy = std::get<1>(wire);
tsMaxEnergy = std::get<2>(wire);
}
}
avgvec.first = avgvec.first * (1.0 / sumEnergy);
avgvec.second = avgvec.second * (1.0 / sumEnergy);
double phi1 = avgvec.first.Phi();
double phi2 = avgvec.second.Phi();
avgvec.first.SetXYZ(radiusC * TMath::Cos(phi1), radiusC * TMath::Sin(phi1), -zLen / 2);
avgvec.second.SetXYZ(radiusC * TMath::Cos(phi2), radiusC * TMath::Sin(phi2), zLen / 2);
}
return std::tuple(avgvec, sumEnergy, maxEnergy, tsMaxEnergy);
}
inline std::tuple<TVector3, double, double, double, double, double, double, double> PW::FindCrossoverProperties(const std::vector<std::tuple<int, double, double>> &a_cluster,
const std::vector<std::tuple<int, double, double>> &c_cluster)
{
// std::pair<TVector3, TVector3> apwire = GetPseudoWire(a_cluster,"ANODE",anodeSumE);
// std::pair<TVector3, TVector3> cpwire = GetPseudoWire(c_cluster,"CATHODE",cathodeSumE);
auto [apwire, apSumE, apMaxE, apTSMaxE] = GetPseudoWire(a_cluster, "ANODE");
auto [cpwire, cpSumE, cpMaxE, cpTSMaxE] = GetPseudoWire(c_cluster, "CATHODE");
TVector3 crossover;
crossover.Clear();
TVector3 a, c, diff;
double a2, ac, c2, adiff, cdiff, denom, alpha = 0;
if (apSumE && cpSumE)
{
a = apwire.first - apwire.second;
c = cpwire.first - cpwire.second;
diff = apwire.first - cpwire.first;
a2 = a.Dot(a);
c2 = c.Dot(c);
ac = a.Dot(c);
adiff = a.Dot(diff);
cdiff = c.Dot(diff);
denom = a2 * c2 - ac * ac;
alpha = (ac * cdiff - c2 * adiff) / denom;
crossover = apwire.first + alpha * a;
if (crossover.z() < -190 || crossover.Z() > 190)
{
alpha = 9999999;
apSumE = -1;
cpSumE = -1;
apMaxE = -1;
cpMaxE = -1;
apTSMaxE = -1;
cpTSMaxE = -1;
}
}
// std::cout << apSumE << " " << cpSumE << " " << " " << crossover.Perp() << std::endl;
return std::tuple(crossover, alpha, apSumE, cpSumE, apMaxE, cpMaxE, apTSMaxE, cpTSMaxE);
}
inline void PW::FindWireID(TVector3 pos, TVector3 direction, bool verbose)
{
hitInfo.Clear(); hitInfo.Clear();
double phi = direction.Phi(); double phi = direction.Phi();
for( int i = 0; i < nWire; i++){ for (int i = 0; i < nWire; i++)
{
double disA = 99999999; double disA = 99999999;
double phiS = An[i].first.Phi() - TMath::PiOver4(); double phiS = An[i].first.Phi() - TMath::PiOver4();
double phiL = An[i].second.Phi() + TMath::PiOver4(); double phiL = An[i].second.Phi() + TMath::PiOver4();
// printf("A%2d: %f %f | %f\n", i, phiS * TMath::RadToDeg(), phiL * TMath::RadToDeg(), phi * TMath::RadToDeg()); // printf("A%2d: %f %f | %f\n", i, phiS * TMath::RadToDeg(), phiL * TMath::RadToDeg(), phi * TMath::RadToDeg());
if( phi > 0 && phiS > phiL ) phiL = phiL + TMath::TwoPi(); if (phi > 0 && phiS > phiL)
if( phi < 0 && phiS > phiL ) phiS = phiS - TMath::TwoPi(); phiL = phiL + TMath::TwoPi();
if (phi < 0 && phiS > phiL)
phiS = phiS - TMath::TwoPi();
if( phiS < phi && phi < phiL) { if (phiS < phi && phi < phiL)
disA = Distance( pos, pos + direction, An[i].first, An[i].second); {
if( disA < hitInfo.nearestDist.first ){ disA = Distance(pos, pos + direction, An[i].first, An[i].second);
if (disA < hitInfo.nearestDist.first)
{
hitInfo.nearestDist.first = disA; hitInfo.nearestDist.first = disA;
hitInfo.nearestWire.first = i; hitInfo.nearestWire.first = i;
} }
} }
double disC = 99999999; double disC = 99999999;
phiS = Ca[i].second.Phi()- TMath::PiOver4(); phiS = Ca[i].second.Phi() - TMath::PiOver4();
phiL = Ca[i].first.Phi() + TMath::PiOver4(); phiL = Ca[i].first.Phi() + TMath::PiOver4();
// printf("C%2d: %f %f\n", i, phiS * TMath::RadToDeg(), phiL * TMath::RadToDeg()); // printf("C%2d: %f %f\n", i, phiS * TMath::RadToDeg(), phiL * TMath::RadToDeg());
if( phi > 0 && phiS > phiL ) phiL = phiL + TMath::TwoPi(); if (phi > 0 && phiS > phiL)
if( phi < 0 && phiS > phiL ) phiS = phiS - TMath::TwoPi(); phiL = phiL + TMath::TwoPi();
if (phi < 0 && phiS > phiL)
phiS = phiS - TMath::TwoPi();
if(phiS < phi && phi < phiL) { if (phiS < phi && phi < phiL)
disC = Distance( pos, pos + direction, Ca[i].first, Ca[i].second); {
if( disC < hitInfo.nearestDist.second ){ disC = Distance(pos, pos + direction, Ca[i].first, Ca[i].second);
if (disC < hitInfo.nearestDist.second)
{
hitInfo.nearestDist.second = disC; hitInfo.nearestDist.second = disC;
hitInfo.nearestWire.second = i; hitInfo.nearestWire.second = i;
} }
} }
if(verbose) printf(" %2d | %8.2f, %8.2f\n", i, disA, disC); if (verbose)
printf(" %2d | %8.2f, %8.2f\n", i, disA, disC);
} }
//==== find the 2nd nearest wire //==== find the 2nd nearest wire
short anode1 = hitInfo.nearestWire.first; short anode1 = hitInfo.nearestWire.first;
short aaa1 = anode1 - 1; if( aaa1 < 0 ) aaa1 += nWire; short aaa1 = anode1 - 1;
if (aaa1 < 0)
aaa1 += nWire;
short aaa2 = (anode1 + 1) % nWire; short aaa2 = (anode1 + 1) % nWire;
double haha1 = Distance( pos, pos + direction, An[aaa1].first, An[aaa1].second); double haha1 = Distance(pos, pos + direction, An[aaa1].first, An[aaa1].second);
double haha2 = Distance( pos, pos + direction, An[aaa2].first, An[aaa2].second); double haha2 = Distance(pos, pos + direction, An[aaa2].first, An[aaa2].second);
if( haha1 < haha2){ if (haha1 < haha2)
{
hitInfo.nextNearestWire.first = aaa1; hitInfo.nextNearestWire.first = aaa1;
hitInfo.nextNearestDist.first = haha1; hitInfo.nextNearestDist.first = haha1;
}else{ }
else
{
hitInfo.nextNearestWire.first = aaa2; hitInfo.nextNearestWire.first = aaa2;
hitInfo.nextNearestDist.first = haha2; hitInfo.nextNearestDist.first = haha2;
} }
short cathode1 = hitInfo.nearestWire.second; short cathode1 = hitInfo.nearestWire.second;
short ccc1 = cathode1 - 1; if( ccc1 < 0 ) ccc1 += nWire; short ccc1 = cathode1 - 1;
if (ccc1 < 0)
ccc1 += nWire;
short ccc2 = (cathode1 + 1) % nWire; short ccc2 = (cathode1 + 1) % nWire;
haha1 = Distance( pos, pos + direction, Ca[ccc1].first, Ca[ccc1].second); haha1 = Distance(pos, pos + direction, Ca[ccc1].first, Ca[ccc1].second);
haha2 = Distance( pos, pos + direction, Ca[ccc2].first, Ca[ccc2].second); haha2 = Distance(pos, pos + direction, Ca[ccc2].first, Ca[ccc2].second);
if( haha1 < haha2){ if (haha1 < haha2)
{
hitInfo.nextNearestWire.second = ccc1; hitInfo.nextNearestWire.second = ccc1;
hitInfo.nextNearestDist.second = haha1; hitInfo.nextNearestDist.second = haha1;
}else{ }
else
{
hitInfo.nextNearestWire.second = ccc2; hitInfo.nextNearestWire.second = ccc2;
hitInfo.nextNearestDist.second = haha2; hitInfo.nextNearestDist.second = haha2;
} }
if( verbose ) Print(); if (verbose)
Print();
} }
inline void PW::CalTrack(TVector3 sx3Pos, int anodeID, int cathodeID, bool verbose){ inline void PW::CalTrack(TVector3 sx3Pos, int anodeID, int cathodeID, bool verbose)
{
trackPos = sx3Pos; trackPos = sx3Pos;
@ -231,72 +573,116 @@ inline void PW::CalTrack(TVector3 sx3Pos, int anodeID, int cathodeID, bool verbo
// if the handiness of anode and cathode revered, it should be n2 cross n1 // if the handiness of anode and cathode revered, it should be n2 cross n1
trackVec = (n2.Cross(n1)).Unit(); trackVec = (n2.Cross(n1)).Unit();
if( verbose ) printf("Theta, Phi = %f, %f \n", trackVec.Theta() *TMath::RadToDeg(), trackVec.Phi()*TMath::RadToDeg()); if (verbose)
printf("Theta, Phi = %f, %f \n", trackVec.Theta() * TMath::RadToDeg(), trackVec.Phi() * TMath::RadToDeg());
} }
inline void PW::CalTrack2(TVector3 sx3Pos, PWHitInfo hitInfo, double sigmaA, double sigmaC, bool verbose){ inline void PW::CalTrack2(TVector3 siPos, TVector3 anodeInt, bool verbose)
{
trackPos = sx3Pos; double mx, my;
double z;
double p1 = TMath::Abs(hitInfo.nearestDist.first + gRandom->Gaus(0, sigmaA)); mx = siPos.X() / (siPos.X() - anodeInt.X());
double p2 = TMath::Abs(hitInfo.nextNearestDist.first + gRandom->Gaus(0, sigmaA)); my = siPos.Y() / (siPos.Y() - anodeInt.Y());
double fracA = p1 / (p1 + p2); z = siPos.Z() + mx * (anodeInt.Z() - siPos.Z());
short anodeID1 = hitInfo.nearestWire.first; // if (mx == my)
short anodeID2 = hitInfo.nextNearestWire.first; {
TVector3 shiftA1 = (An[anodeID2].first - An[anodeID1].first) * fracA; trackVec = TVector3(0, 0, z);
TVector3 shiftA2 = (An[anodeID2].second - An[anodeID1].second) * fracA; }
double q1 = TMath::Abs(hitInfo.nearestDist.second + gRandom->Gaus(0, sigmaC));
double q2 = TMath::Abs(hitInfo.nextNearestDist.second + gRandom->Gaus(0, sigmaC));
double fracC = q1 / (q1 + q2);
short cathodeID1 = hitInfo.nearestWire.second;
short cathodeID2 = hitInfo.nextNearestWire.second;
TVector3 shiftC1 = (Ca[cathodeID2].first - Ca[cathodeID1].first) * fracC;
TVector3 shiftC2 = (Ca[cathodeID2].second - Ca[cathodeID1].second) * fracC;
TVector3 a1 = An[anodeID1].first + shiftA1;
TVector3 a2 = An[anodeID1].second + shiftA2;
TVector3 c1 = Ca[cathodeID1].first + shiftC1;
TVector3 c2 = Ca[cathodeID1].second + shiftC2;
TVector3 n1 = (a1 - a2).Cross((sx3Pos - a2)).Unit();
TVector3 n2 = (c1 - c2).Cross((sx3Pos - c2)).Unit();
// if the handiness of anode and cathode revered, it should be n2 cross n1
trackVec = (n2.Cross(n1)).Unit();
if( verbose ) printf("Theta, Phi = %f, %f \n", trackVec.Theta() *TMath::RadToDeg(), trackVec.Phi()*TMath::RadToDeg());
if (verbose)
printf("X slope = %f and Y slope = %f \n", mx, my);
} }
inline double PW::GetZ0(){ /*inline TVector3 PW::CalTrack3(TVector3 siPos, TVector3 anodeInt, bool verbose)
{
TVector3 v = anodeInt-siPos;
double t_minimum = -1.0*(siPos.X()*v.X()+siPos.Y()*v.Y())/(v.X()*v.X()+v.Y()*v.Y());
TVector3 vector_closest_to_z = siPos + t_minimum*v;
return vector_closest_to_z;
if (verbose)
printf("X slope = %f and Y slope = %f \n", mx, my);
}*/
inline double PW::GetZ0()
{
double x = trackPos.X(); double x = trackPos.X();
double y = trackPos.Y(); double y = trackPos.Y();
double rho = TMath::Sqrt(x*x + y*y); double rho = TMath::Sqrt(x * x + y * y);
double theta = trackVec.Theta(); double theta = trackVec.Theta();
return trackPos.Z() - rho / TMath::Tan(theta); return trackVec.Z();
}
// Each wire family is strung as straight skew chords between two rings, so it sweeps a
// one-sheet hyperboloid (x*x+y*y)/(a*a) - (z*z)/(c*c) = 1 whose waist 'a' is smaller than
// the ring radius. The anode waist was fit to the measured anode crossover points; the
// other families share the flare 'c' and scale their waist with the ring radius.
//
// Radial ordering, inner to outer: guard (ring 32) < anode (ring 37) < cathode (ring 43).
// Charge collection spans guard -> cathode. The anodes in the middle are the readout, the
// cathodes see the induced/mirror charge, and the guard wires are field-shaping, not read out.
const double kPCHyperbC = 301.895;
const double kPCAnodeWaist = 32.0429; // ring radius 37 mm -- readout
const double kPCCathodeWaist = 32.0429 * 42.0 / 37.0; // ring radius 43 mm -- induced charge
const double kPCGuardWaist = 32.0429 * 32.0 / 37.0; // ring radius 32 mm -- not read out
// Intersection of the segment x1 -> x1+dx with the one-sheet hyperboloid of waist a, flare c.
// Returns TVector3(0, 0, 54321) when the segment does not cross the surface.
inline TVector3 pc_hyperboloid_intersect(const TVector3 &x1, const TVector3 &dx, double a, double c)
{
double t2 = 1.0; // value of 't' at the destination point, by definition t=(z(t)-z0)/dz
auto A = pow(dx.Perp(), 2) / (a * a) - pow(dx.Z(), 2) / (c * c);
auto B = 2 * (dx.X() * x1.X() + dx.Y() * x1.Y()) / (a * a) - 2 * (dx.Z() * x1.Z()) / (c * c);
auto C = pow(x1.Perp(), 2) / (a * a) - pow(x1.Z(), 2) / (c * c) - 1.0;
double disc = B * B - 4 * A * C;
if (disc < 0)
return TVector3(0, 0, 54321);
double tsol1 = (-B + TMath::Sqrt(disc)) / (2 * A);
double tsol2 = (-B - TMath::Sqrt(disc)) / (2 * A);
if (tsol1 >= 0 && tsol1 <= t2)
return x1 + tsol1 * dx;
else if (tsol2 >= 0 && tsol2 <= t2)
return x1 + tsol2 * dx;
else
return TVector3(0, 0, 54321);
} }
inline double PW::CircularMean(std::vector<std::pair<int, double>> wireList){ inline std::tuple<TVector3, TVector3, double> find_PC_PathLength(const TVector3 &x1, const TVector3 &x2)
{
//use unit vector, wireID start from Zero /*
double xCom = 0, yCom = 0; Anode -> cathode segment for a particle moving from x1 to x2.
for( size_t i = 0; i < wireList.size() ; i++){ * Typical arguments here will be x1=r_rhoMin, x2=qqqevent.pos or sx3event.pos
xCom += TMath::Cos(TMath::TwoPi() * wireList[i].first / nWire) * wireList[i].second; * Returns {cathode_intersect, anode_intersect, gap_in_cm}; gap == 54321 sentinel on failure.
yCom += TMath::Sin(TMath::TwoPi() * wireList[i].first / nWire) * wireList[i].second; * NOTE: this is the anode->cathode gap, NOT the full charge-collection region.
} For the anode energy calibration use find_PC_CollectionPath() instead.
*/
//calculate the angle of the summed unit vectors TVector3 dx = x2 - x1; // direction vector
double angle = TMath::ATan2(yCom, xCom); TVector3 anode_intersect = pc_hyperboloid_intersect(x1, dx, kPCAnodeWaist, kPCHyperbC);
if( angle < 0 ) angle += TMath::TwoPi(); // convert the angle from 0 to 2 pi TVector3 cathode_intersect = pc_hyperboloid_intersect(x1, dx, kPCCathodeWaist, kPCHyperbC);
if (anode_intersect.Z() != 54321 && cathode_intersect.Z() != 54321)
return angle/ TMath::TwoPi() * nWire; return std::tuple(cathode_intersect, anode_intersect, (cathode_intersect - anode_intersect).Mag() * 0.1);
else
return std::tuple(TVector3(0, 0, 0), TVector3(0, 0, 0), 54321);
}
inline std::tuple<TVector3, TVector3, double> find_PC_CollectionPath(const TVector3 &x1, const TVector3 &x2)
{
/*
Charge-collection region for a particle moving from x1 to x2: it begins where the track
passes the guard wires and ends at the cathode. This is the segment whose energy deposit
the anodes actually collect, so it is the dE target for the anode energy calibration.
* Returns {guard_intersect, cathode_intersect, thickness_in_cm}; 54321 sentinel on failure.
*/
TVector3 dx = x2 - x1;
TVector3 guard_intersect = pc_hyperboloid_intersect(x1, dx, kPCGuardWaist, kPCHyperbC);
TVector3 cathode_intersect = pc_hyperboloid_intersect(x1, dx, kPCCathodeWaist, kPCHyperbC);
if (guard_intersect.Z() != 54321 && cathode_intersect.Z() != 54321)
return std::tuple(guard_intersect, cathode_intersect, (cathode_intersect - guard_intersect).Mag() * 0.1);
else
return std::tuple(TVector3(0, 0, 0), TVector3(0, 0, 0), 54321);
} }
#endif #endif

355
Armory/EventBuilder.cpp Normal file
View File

@ -0,0 +1,355 @@
#include "fsuReader.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TClonesArray.h"
#include "TGraph.h"
#include "TFile.h"
#include "TTree.h"
#include "TMacro.h"
#define MAX_MULTI 2000
struct FileInfo{
std::string fileName;
int fileID;
unsigned long hitCount;
};
//^#############################################################
//^#############################################################
int main(int argc, char **argv) {
printf("=========================================\n");
printf("=== *.fsu Events Builder ===\n");
printf("=========================================\n");
if (argc < 6) {
printf("Incorrect number of arguments:\n");
printf("%s [timeWindow] [withTrace] [verbose] [batchSize] [inFile1] [inFile2] .... \n", argv[0]);
printf(" timeWindow : in ns, -1 = no event building \n");
printf(" withTrace : 0 for no trace, 1 for trace \n");
printf(" verbose : > 0 for debug \n");
printf(" batchSize : the size of hit in a batch \n");
printf(" Output file name is contructed from inFile1 \n");
printf("\n");
printf(" Example: %s 0 0 0 10000 '\\ls -1 *001*.fsu'\n", argv[0]);
printf("\n\n");
return 1;
}
uInt runStartTime = getTime_us();
///============= read input
long timeWindow = atoi(argv[1]);
bool traceOn = atoi(argv[2]);
unsigned int debug = atoi(argv[3]);
unsigned int batchSize = atoi(argv[4]);
int nFile = argc - 5;
TString inFileName[nFile];
for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i+5];}
/// Form outFileName;
TString outFileName = inFileName[0];
int pos = outFileName.Last('/');
pos = outFileName.Index("_", pos+1); // find next "_"
pos = outFileName.Index("_", pos+1); // find next "_"
if( nFile == 1 ) pos = outFileName.Index("_", pos+1); // find next "_", S/N
outFileName.Remove(pos); // remove the rest
outFileName += "_" + std::to_string(timeWindow);
outFileName += ".root";
printf("-------> Out file name : %s \n", outFileName.Data());
printf("========================================= Number of Files : %d \n", nFile);
for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].Data());
printf("=========================================\n");
printf(" Time Window = %ld ns = %.1f us\n", timeWindow, timeWindow/1000.);
printf(" Include Trace = %s\n", traceOn ? "Yes" : "No");
printf(" Debug level = %d\n", debug);
printf(" Batch size = %d events/file\n", batchSize);
printf(" Max multiplity = %d hits/event (hard coded)\n", MAX_MULTI);
printf("========================================= Grouping files\n");
std::vector<std::vector<FileInfo>> fileGroupList; // fileName and ID = SN * 1000 + index
std::vector<FileInfo> fileList;
unsigned long long int totalHitCount = 0;
FSUReader * readerA = new FSUReader(inFileName[0].Data(), 1, 1);
readerA->ScanNumBlock(0,0);
FileInfo fileInfo = {inFileName[0].Data(), readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetHitCount()};
fileList.push_back(fileInfo);
totalHitCount += readerA->GetHitCount();
for( int i = 1; i < nFile; i++){
FSUReader * readerB = new FSUReader(inFileName[i].Data(), 1, 0);
readerB->ScanNumBlock(0,0);
totalHitCount += readerB->GetHitCount();
fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetHitCount()};
if( readerA->GetSN() == readerB->GetSN() ){
fileList.push_back(fileInfo);
}else{
fileGroupList.push_back(fileList);
fileList.clear();
fileList.push_back(fileInfo);
}
delete readerA;
readerA = readerB;
}
fileGroupList.push_back(fileList);
delete readerA;
printf("======================= total Hit Count : %llu\n", totalHitCount);
for( size_t i = 0; i < fileGroupList.size(); i++){
printf("group ----- %ld \n", i);
//sort by ID
std::sort(fileGroupList[i].begin(), fileGroupList[i].end(), [](const FileInfo & a, const FileInfo & b) {
return a.fileID < b.fileID;
});
for( size_t j = 0; j < fileGroupList[i].size(); j++){
printf("%3ld | %8d | %9lu| %s \n", j, fileGroupList[i][j].fileID, fileGroupList[i][j].hitCount, fileGroupList[i][j].fileName.c_str() );
}
}
// //*====================================== create tree
TFile * outRootFile = new TFile(outFileName, "recreate");
TTree * tree = new TTree("tree", outFileName);
unsigned long long evID = 0;
unsigned int multi = 0;
unsigned short sn[MAX_MULTI] = {0}; /// board SN
unsigned short ch[MAX_MULTI] = {0}; /// chID
unsigned short e[MAX_MULTI] = {0}; /// 15 bit
unsigned short e2[MAX_MULTI] = {0}; /// 15 bit
unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit
unsigned short e_f[MAX_MULTI] = {0}; /// fine time 10 bit
unsigned short traceLength[MAX_MULTI];
tree->Branch("evID", &evID, "event_ID/l");
tree->Branch("multi", &multi, "multi/i");
tree->Branch("sn", sn, "sn[multi]/s");
tree->Branch("ch", ch, "ch[multi]/s");
tree->Branch("e", e, "e[multi]/s");
tree->Branch("e2", e2, "e2[multi]/s");
tree->Branch("e_t", e_t, "e_timestamp[multi]/l");
tree->Branch("e_f", e_f, "e_fineTime[multi]/s");
tree->Branch("traceLength", traceLength, "traceLength[multi]/s");
TClonesArray * arrayTrace = nullptr;
TGraph * trace = nullptr;
if( traceOn ) {
arrayTrace = new TClonesArray("TGraph");
tree->Branch("trace", arrayTrace, 2560000);
arrayTrace->BypassStreamer();
}
//*======================================= Open files
printf("========================================= Open files & Build Events.\n");
const short nGroup = fileGroupList.size();
std::vector<Hit> hitList[nGroup];
FSUReader ** reader = new FSUReader * [nGroup];
ulong ID[nGroup];
for( short i = 0; i < nGroup; i++){
std::vector<std::string> fList;
for( size_t j = 0; j < fileGroupList[i].size(); j++){
fList.push_back( fileGroupList[i][j].fileName );
}
reader[i] = new FSUReader(fList, 600, debug);
hitList[i] = reader[i]->ReadBatch(batchSize, debug );
reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN()));
ID[i] = 0;
if( debug ) {
for( size_t p = 0; p < 10; p ++ ){
if( hitList[i].size() <= p ) break;
hitList[i][p].Print();
}
}
}
unsigned long long tStart = 0;
unsigned long long tEnd = 0;
//find earliest time group;
unsigned long long t0 = -1;
short g0 = 0 ;
for( short i = 0; i < nGroup; i++){
if( hitList[i].size() == 0 ) continue;
if( hitList[i][0].timestamp < t0 ) {
t0 = hitList[i][0].timestamp;
g0 = i;
}
}
tStart = t0;
if( debug ) printf("First timestamp is %llu, group : %u\n", t0, g0);
int nFileFinished = 0;
multi = 0;
evID = 0;
std::vector<Hit> events;
unsigned long long hitProcessed = 0;
do{
//*============= Build events from hitList[i]
if( debug ) printf("################################ ev build %llu \n", evID);
events.clear();
for( short i = 0; i < nGroup; i++){
short ig = (i + g0 ) % nGroup;
if( hitList[ig].size() == 0 ) continue;
//chekc if reached the end of hitList
if( ID[ig] >= hitList[ig].size() ) {
hitList[ig] = reader[ig]->ReadBatch(batchSize, debug + 1);
if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig));
ID[ig] = 0;
if( hitList[ig].size() == 0 ) continue;
}
if( timeWindow >= 0 ){
do{
if( (long int)(hitList[ig].at(ID[ig]).timestamp - t0) <= timeWindow ){
events.push_back(hitList[ig].at(ID[ig]));
ID[ig] ++;
}else{
break;
}
//check if reached the end of hitList
if( ID[ig] >= hitList[ig].size() ) {
hitList[ig] = reader[ig]->ReadBatch(batchSize, debug);
if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig));
ID[ig] = 0;
if( hitList[ig].size() == 0 ) break;
}
}while(ID[ig] < hitList[ig].size());
}else{
events.push_back(hitList[ig].at(ID[ig]));
ID[ig] ++;
}
if( timeWindow < 0) break;
}
if( events.size() > 1 ){
std::sort(events.begin(), events.end(), [](const Hit& a, const Hit& b) {
return a.timestamp < b.timestamp;
});
}
tEnd = events.back().timestamp;
hitProcessed += events.size();
if( hitProcessed % 10000 == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount);
multi = events.size() ;
if( events.size() >= MAX_MULTI ) {
printf("event %lld has size = %d > MAX_MULTI = %d\n", evID, multi, MAX_MULTI);
multi = MAX_MULTI;
}
if( debug ) printf("=================================== filling data | %u \n", multi);
for( size_t p = 0; p < multi ; p ++ ) {
if( debug ) {printf("%4zu | ", p); events[p].Print();}
sn[p] = events[p].sn;
ch[p] = events[p].ch;
e[p] = events[p].energy;
e2[p] = events[p].energy2;
e_t[p] = events[p].timestamp;
e_f[p] = events[p].fineTime;
traceLength[p] = events[p].traceLength;
if( traceOn ){
trace = (TGraph *) arrayTrace->ConstructedAt(multi, "C");
trace->Clear();
for( int hh = 0; hh < traceLength[multi]; hh++){
trace->SetPoint(hh, hh, events[p].trace[hh]);
}
}
}
outRootFile->cd();
tree->Fill();
// tree->Write();
multi = 0;
evID ++;
///===================== find the next first timestamp
t0 = -1;
g0 = -1;
for( int i = 0; i < nGroup; i++) {
if( hitList[i].size() == 0 ) continue;
if( hitList[i][ID[i]].timestamp < t0 ) {
t0 = hitList[i][ID[i]].timestamp;
g0 = i;
}
}
if( debug ) printf("Next First timestamp is %llu, group : %u\n", t0, g0);
//*=============
nFileFinished = 0;
for( int i = 0 ; i < nGroup; i++) {
if( hitList[i].size() == 0 ) {
nFileFinished ++;
continue;
}else{
if( ID[i] >= hitList[i].size( )) {
hitList[i] = reader[i]->ReadBatch(batchSize, debug);
ID[i] = 0;
if( hitList[i].size() == 0 ) nFileFinished ++;
}
}
}
if( debug > 1 ) printf("========== nFileFinished : %d\n", nFileFinished);
}while( nFileFinished < nGroup);
tree->Write();
uInt runEndTime = getTime_us();
double runTime = (runEndTime - runStartTime) * 1e-6;
printf("========================================= finished.\n");
printf(" event building time = %.2f sec = %.2f min\n", runTime, runTime/60.);
printf(" total events built = %llu by event builder (%llu in tree)\n", evID, tree->GetEntriesFast());
double tDuration_sec = (tEnd - tStart) * 1e-9;
printf(" first timestamp = %20llu ns\n", tStart);
printf(" last timestamp = %20llu ns\n", tEnd);
printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.);
printf("==============> saved to %s \n", outFileName.Data());
TMacro info;
info.AddLine(Form("tStart= %20llu ns",tStart));
info.AddLine(Form(" tEnd= %20llu ns",tEnd));
info.Write("info");
outRootFile->Close();
for( int i = 0; i < nGroup; i++) delete reader[i];
delete [] reader;
return 0;
}

491
Armory/HistPlotter.h Normal file
View File

@ -0,0 +1,491 @@
#ifndef HISTPLOTTER_H
#define HISTPLOTTER_H
#include <TCanvas.h>
#include <TROOT.h>
#include <TSystem.h>
#include <TStyle.h>
#include <iostream>
#include <TFile.h>
#include <TMemFile.h>
#include <TH1.h>
#include <TH2.h>
#include <TCutG.h>
#include <signal.h>
#include <cstdlib>
#include <utility>
#include <fstream>
#include <sstream>
#include <map>
#include <unordered_map>
#include <set>
#include <TGraphErrors.h>
class HistPlotter
{
private:
long long barrier_count, barrier_limit; // meant to keep track of how often to call FillN() on histograms
enum
{
TFILE,
TMEMFILE
} filetype;
std::map<std::string, TObject *> oMap; //!< Maps std::string to all TH1, TH2 objects in the class
std::unordered_map<std::string, TObject *> cutsMap; //!< Maps std::string to TCutG objects held by the class
std::set<std::string> folderList; //!< List of all folder names used to nest objects
std::unordered_map<TObject *, std::string> foldersForObjects; //!< Map that returns the folder corresponding to the object whose pointer is specified
TFile *ofile = nullptr; //!< TFile pointer for the output file
TMemFile *omfile = nullptr; //!< TFile pointer for the output memfile
// Caches to permit FillN() calls
std::map<std::string, std::vector<double>> onedimcache;
std::map<std::string, std::pair<std::vector<double>, std::vector<double>>> twodimcache;
inline void FillN_All_Histograms();
public:
HistPlotter(std::string outfile, std::string type);
inline void FlushToDisk(int integral); //!< Writes all objects to file before closing, nesting objects in folders as is found necessary
inline void PrintObjects(); //!< Dump objects to std::cout for inspection
inline void ReadCuts(std::string);
inline TCutG *FindCut(std::string cut)
{
return static_cast<TCutG *>(cutsMap.at(cut));
}
inline void set_barrier_limit(long long limit) { barrier_limit = limit; }
inline void barrier_increment()
{
barrier_count++;
if (barrier_count == barrier_limit)
{
FillN_All_Histograms();
barrier_count = 0;
}
}
inline void force_flush_caches()
{
FillN_All_Histograms();
barrier_count = 0;
}
/*! \fn void FindCut()
\brief
- Searches for a cut by name 'cut' in the internal list of cuts 'cutsMap'. Ugly fails (via unresolved at()) if such a cut isn't found.
\param filename - name of the plainxtext file containing the cut file locations and identifiers
\return Pointer to the TCutG object that matches the name. Very useful to use this as plotter.FindCut("protonbarrelpid")->IsInside(deltaE, E) for instance.
*/
inline void SetNewTitle(std::string name, std::string title)
{
auto result = oMap.find(name); // result is an iterator
if (result == oMap.end())
return; // no warnings, could be changed in future
else
static_cast<TNamed *>(oMap.at(name))->SetTitle(title.c_str()); // set new title
}
// Smart functions that create a new histogram if it doesn't exist.
inline void FillGraph(const std::string &name, float valuex, float valuey, float errx = 0, float erry = 0);
inline void Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value);
inline void Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey);
inline void Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value, const std::string &folder);
inline void Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey, const std::string &folder);
// TObject* findObject(std::string key);
};
HistPlotter::HistPlotter(std::string outfile, std::string type = "")
{
/*!
\brief Constructor. Opens a TFile instance with the specified filename
\param outfile : std::string that holds the desired output ROOT filename
\return None
*/
if (type == "" || type == "TFILE")
{
ofile = new TFile(outfile.c_str(), "recreate");
filetype = TFILE;
}
else if (type == "TMEMFILE")
{
omfile = new TMemFile(outfile.c_str(), "recreate");
filetype = TMEMFILE;
}
else
{
std::cout << "Unknown type " << type << " specified for HistPlotter (use \"TFILE\" or \"TMEMFILE\"), using default \"TFILE\" " << std::endl;
ofile = new TFile(outfile.c_str(), "recreate");
filetype = TFILE;
}
barrier_count = 0;
barrier_limit = 1000;
}
void HistPlotter::FillN_All_Histograms()
{
for (auto it = oMap.begin(); it != oMap.end(); it++)
{
// it->first is std::string 'name', it->second is the TObject
if (it->second->InheritsFrom("TH1F"))
{
// FillN(size, array-of-doubles, array-of-weights); //we set array-of-weights to (1,1,1,.. (size)
static_cast<TH1F *>(it->second)->FillN(onedimcache[it->first].size(), // size
onedimcache[it->first].data(), // array
std::vector<double>(onedimcache[it->first].size(), 1.0).data()); // weight of ones
onedimcache[it->first].clear();
}
else if (it->second->InheritsFrom("TH2F"))
{
// FillN(size, array-of-doubles, array-of-weights); //we set array-of-weights to (1,1,1,.. (size))
static_cast<TH2F *>(it->second)->FillN(twodimcache[it->first].first.size(), // size
twodimcache[it->first].first.data(), // x array
twodimcache[it->first].second.data(), // y array
std::vector<double>(twodimcache[it->first].first.size(), 1.0).data()); // weight of ones
twodimcache[it->first].first.clear();
twodimcache[it->first].second.clear();
}
}
std::cout << "." << std::endl;
}
void HistPlotter::FlushToDisk(int min_integral = 0)
{
/*! \fn void FlushToDisk()
\brief Function that can be used at any point to exit smoothly by saving all ROOT objects in memory
to the output file before closing it. Obeys the binding of histograms to separate folders, if so specified.
\return No return -- void
*/
if (filetype == TMEMFILE && omfile)
{
std::cout << "Not flushing a TMemfile .. exiting .." << std::endl;
delete omfile;
return;
}
if (ofile->IsZombie() || !ofile)
{
std::cerr << "Output file is zombie, finishing up without writing to disk!" << std::endl;
return;
}
FillN_All_Histograms();
for (auto it = oMap.begin(); it != oMap.end(); it++)
{
// omap maps: name(first) to object address(second).
// foldersForObjects maps: object address(first) to foldername(second)
auto result = foldersForObjects.find(it->second); // returns <TObject* histogram,std::string foldername> pair if found
if (result != foldersForObjects.end())
{ // we try to create folder if needed and cd to it
ofile->mkdir(result->second.c_str(), "", kTRUE); // args: name, title, returnExistingDirectory
ofile->cd(result->second.c_str());
}
else
{
ofile->cd(); // toplevel for all default histograms. Default setting
}
if (((TH1F *)it->second)->Integral() > min_integral)
it->second->Write();
}
// Create a directory for all cuts, and save all cuts in them
ofile->mkdir("gCUTS", "", kTRUE);
ofile->cd("gCUTS");
for (auto it = cutsMap.begin(); it != cutsMap.end(); it++)
{
(static_cast<TNamed *>(it->second))->SetName(it->first.c_str());
it->second->Write();
}
ofile->Close();
std::cout << "Wrote " << oMap.size() << " histograms to TFile " << std::string(ofile->GetName()) << std::endl;
}
void HistPlotter::FillGraph(const std::string &name, float valuex, float valuey, float errx, float erry)
{
/*! \fn void FillGraph()
\brief
- Creates a TGraphError in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
- Writes present state to disk and fails with return value -1 if the name clashes with another object that's not of type TGraph*
\param name name of the TGraph
\param valuex The xvalue
\param valuey The yvalue
\param errx The x error
\param erry The y error
\return No return void
*/
auto result = oMap.find(name);
if (result == oMap.end())
{
TGraphErrors *tempG = new TGraphErrors();
tempG->SetName(name.c_str());
oMap.insert(std::make_pair(name, static_cast<TObject *>(tempG)));
}
if (!oMap.at(name)->InheritsFrom("TGraphErrors"))
{
std::cerr << "Object " << name << " refers to something other than a TGraph*, not filling it hence!" << std::endl;
std::cerr << "Abort.." << std::endl;
FlushToDisk();
exit(-1);
}
// static_cast<TGraphErrors*>(oMap.at(name))->AddPointError(valuex,valuey,errx,erry);
}
void HistPlotter::Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value)
{
/*! \fn void Fill1D()
\brief
- Creates a TH1F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
- Writes present state to disk and fails with return value -1 if the name clashes with another object that's not of type TH1*
\param name name of the TH1F histogram
\param nbinsx Number of bins in the histogram
\param xlow Lower limit on x-axis
\param xhigh Upper limit on x-axis
\param value The bin corresponding to value in (nbinsx, xlow, xhigh) is incremented by 1
\return No return void
*/
auto result = oMap.find(name); // result is an iterator
if (result == oMap.end())
{
TH1F *temp1D = new TH1F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh);
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp1D)));
onedimcache.insert(std::make_pair(name, std::vector<double>()));
onedimcache[name].reserve(16384);
}
else if (foldersForObjects.find(oMap.at(name)) != foldersForObjects.end())
{ // shouldn't have a folder associated with it
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in toplevel .." << std::endl;
}
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
if (!oMap.at(name)->InheritsFrom("TH1F"))
{
std::cerr << "Object " << name << " refers to something other than a TH1*, not filling it hence!" << std::endl;
std::cerr << "Abort.." << std::endl;
FlushToDisk();
exit(-1);
}
onedimcache[name].emplace_back(value);
// static_cast<TH1F*>(oMap.at(name))->Fill(value);
}
void HistPlotter::Fill1D(const std::string &name, int nbinsx, float xlow, float xhigh, float value, const std::string &foldername)
{
/*! \fn void Fill1D()
\brief
- Creates a TH1F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
- Writes present state to disk and fails with return value -1 if the name clashes with another object that's not of type TH1*
- Remembers the foldername this particular histogram maps to, if provided. If not, defaults to toplevel.
\param name name of the TH1F histogram
\param nbinsx Number of bins in the histogram
\param xlow Lower limit on x-axis
\param xhigh Upper limit on x-axis
\param value The bin corresponding to value in (nbinsx, xlow, xhigh) is incremented by 1
\param foldername Name of the folder to put this histogram into. Defaults to toplevel if left empty
\return No return -- void
*/
auto result = oMap.find(name); // result is an iterator
if (result == oMap.end())
{
TH1F *temp1D = new TH1F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh);
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp1D)));
onedimcache.insert(std::make_pair(name, std::vector<double>()));
onedimcache[name].reserve(16384);
if (foldername != "")
{
if (folderList.find(foldername) == folderList.end())
{
folderList.insert(foldername);
}
foldersForObjects.insert(std::make_pair(static_cast<TObject *>(temp1D), foldername));
}
}
else
{
// object is present in map, but we enforce unique names
// it must already have a folder attached to it
if (foldersForObjects.find(oMap.at(name)) == foldersForObjects.end())
{
std::cerr << "Object " << name << " already registered at toplevel, choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
}
else if (foldersForObjects[oMap[name]] != foldername)
{
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
}
}
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
if (!oMap.at(name)->InheritsFrom("TH1F"))
{
std::cerr << "Object " << name << " refers to something other than a TH1*, not filling it hence!" << std::endl;
std::cerr << "Abort.." << std::endl;
FlushToDisk();
exit(-1);
}
onedimcache[name].emplace_back(value);
// static_cast<TH1F*>(oMap.at(name))->Fill(value);
}
void HistPlotter::Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey)
{
/*! \fn void Fill2D()
\brief
- Creates a TH2F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
- Writes present state to disk and fails with return value -1 if the name clashes with another object that's not of type TH2*
\param name name of the TH1F histogram
\param nbinsx Number of xbins in the histogram
\param xlow Lower limit on x-axis
\param xhigh Upper limit on x-axis
\param nbinsy Number of ybins in the histogram
\param ylow Lower limit on y-axis
\param yhigh Upper limit on y-axis
\param valuex
\param valuey The bin corresponding to (valuex, valuey) in (nbinsx, xlow, xhigh, ybinsx, ylow, yhigh) is incremented by 1
\return No return -- void
*/
auto result = oMap.find(name); // result is an iterator
if (result == oMap.end())
{
TH2F *temp2D = new TH2F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh, nbinsy, ylow, yhigh);
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp2D)));
twodimcache.insert(std::make_pair(name, std::make_pair(std::vector<double>(), std::vector<double>())));
twodimcache[name].first.reserve(16384);
twodimcache[name].second.reserve(16384);
}
else if (foldersForObjects.find(oMap.at(name)) != foldersForObjects.end())
{ // shouldn't have a folder associated with it
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in toplevel .." << std::endl;
}
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
if (!oMap.at(name)->InheritsFrom("TH2F"))
{
std::cerr << "Object " << name << " refers to something other than a TH2*, not filling it hence!" << std::endl;
std::cerr << "Abort.." << std::endl;
FlushToDisk();
exit(-1);
}
twodimcache[name].first.emplace_back(valuex);
twodimcache[name].second.emplace_back(valuey);
// static_cast<TH2F*>(oMap.at(name))->Fill(valuex,valuey);
}
void HistPlotter::Fill2D(const std::string &name, int nbinsx, float xlow, float xhigh, int nbinsy, float ylow, float yhigh, float valuex, float valuey, const std::string &foldername)
{
/*! \fn void Fill2D()
\brief
- Creates a TH2F in memory with name 'name' if it doesn't exist, and fills it with valuex, valuey
- Writes present state to disk and fails with return value -1 if the name clashes with another object that's not of type TH2*
- Remembers the foldername this particular histogram maps to, if provided. If not defaults to toplevel
\param name name of the TH1F histogram
\param nbinsx Number of xbins in the histogram
\param xlow Lower limit on x-axis
\param xhigh Upper limit on x-axis
\param nbinsy Number of ybins in the histogram
\param ylow Lower limit on y-axis
\param yhigh Upper limit on y-axis
\param valuex
\param valuey The bin corresponding to (valuex, valuey) in (nbinsx, xlow, xhigh, ybinsx, ylow, yhigh) is incremented by 1
\param foldername Name of the folder to put this histogram into. Defaults to toplevel if left empty
\return No return -- void
*/
auto result = oMap.find(name); // result is an iterator
if (result == oMap.end())
{
TH2F *temp2D = new TH2F(name.c_str(), name.c_str(), nbinsx, xlow, xhigh, nbinsy, ylow, yhigh);
oMap.insert(std::make_pair(name, static_cast<TObject *>(temp2D)));
twodimcache.insert(std::make_pair(name, std::make_pair(std::vector<double>(), std::vector<double>())));
twodimcache[name].first.reserve(16384);
twodimcache[name].second.reserve(16384);
if (foldername != "")
{
if (folderList.find(foldername) == folderList.end())
{
folderList.insert(foldername);
}
foldersForObjects.insert(std::make_pair(static_cast<TObject *>(temp2D), foldername));
}
}
else
{
// object is present in map, but we enforce unique names
// it must already have a folder attached to it
if (foldersForObjects.find(oMap.at(name)) == foldersForObjects.end())
{
std::cerr << "Object " << name << " already registered at toplevel, choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
}
else if (foldersForObjects[oMap.at(name)] != foldername)
{
std::cerr << "Object " << name << " already registered at " << foldersForObjects[oMap[name]] << ", choose a different name for the histogram to be stored in " << foldername << " folder .." << std::endl;
}
}
// Check if the string 'name' maps to a 1D hist. If there's any other object by this name raise issue
if (!oMap.at(name)->InheritsFrom("TH2F"))
{
std::cerr << "Object " << name << " refers to something other than a TH2*, not filling it hence!" << std::endl;
std::cerr << "Abort.." << std::endl;
FlushToDisk();
exit(-1);
}
twodimcache[name].first.emplace_back(valuex);
twodimcache[name].second.emplace_back(valuey);
// static_cast<TH2F*>(oMap.at(name))->Fill(valuex,valuey);
}
void HistPlotter::ReadCuts(std::string filename)
{
/*! \fn void ReadCuts()
\brief Reads a list of cuts from a file. The file must have the format below, two columns
- Column#1 - path to a file that contains a single TCutG object named "CUTG", the default name in ROOT.
- Column#2 - The identifier name you plan to use in the code, like 'protonbarrelpid' or something, that will be searched by FindCut()
\param filename name of the plainxtext file containing the cut file locations and identifiers
\return No return -- void
*/
std::ifstream infile;
infile.open(filename);
std::string cutfilename, cutname;
for (std::string line; std::getline(infile, line);)
{
if (line.size() != 0 && line[0] == '#')
; // don't do anything with '#' lines
else
{
std::stringstream ss(line);
ss >> cutfilename >> cutname;
TFile f(cutfilename.c_str());
if (f.IsZombie())
{
std::cerr << "Cannot open cutfile " << cutfilename << " .. skipping.." << std::endl;
continue;
}
TCutG *cut = (TCutG *)(f.Get("CUTG"));
cutsMap.insert(std::make_pair(cutname, static_cast<TObject *>(cut)));
f.Close();
} // else
} // for loop
infile.close();
}
void HistPlotter::PrintObjects()
{
/*
void PrintObjects()
Prints the contents of the unordered_maps oMap and cutsMap to facilitate debugging
*/
std::cout << "Type | Name " << std::endl;
std::cout << "---- | --------------------- " << std::endl;
for (auto it = oMap.begin(); it != oMap.end(); it++)
{
std::cout << it->second->ClassName() << " | " << it->first << std::endl;
}
for (auto it = cutsMap.begin(); it != cutsMap.end(); it++)
{
std::cout << it->second->ClassName() << " | " << it->first << std::endl;
}
std::cout << "---- | --------------------- " << std::endl;
}
#endif

52
Armory/Hit.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef Hit_H
#define Hit_H
#include <vector>
class Hit{
public:
unsigned short sn;
uint8_t ch;
unsigned short energy;
unsigned short energy2;
unsigned long long timestamp;
unsigned short fineTime;
bool pileUp;
unsigned short traceLength;
std::vector<short> trace;
Hit(){
Clear();
}
void Clear(){
sn = 0;
ch = 0;
energy = 0;
energy2 = 0;
timestamp = 0;
fineTime = 0;
traceLength = 0;
pileUp = false;
trace.clear();
}
void Print(){
printf("(%5d, %2d) %6d %16llu, %6d, %d, %5ld\n", sn, ch, energy, timestamp, fineTime, pileUp, trace.size());
}
void PrintTrace(){
for( unsigned short i = 0; i < traceLength; i++){
printf("%3u | %6d \n", i, trace[i]);
}
}
// Define operator< for sorting
bool operator<(const Hit& other) const {
return timestamp < other.timestamp;
}
};
#endif

111
Armory/Kinematics.cpp Normal file
View File

@ -0,0 +1,111 @@
#include "Kinematics.h"
//#include "elastcaller.h"
//double Kinematics::getQval(double m1, double m2, double m3, double t1, double t3, double angle3)
double Kinematics::getExc(double t3, double angle3)
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\return Excitation energy of the heavy-recoil nucleus in MeV
*/
{
double m1 = m_A;
double m2 = m_d;
double m3 = m_p;
double m4 = m_B;
double t1 = E_beam;
//t1 = slowitdown("75Ga",t1,"1(12C)2(2H)",1.2);
m1 *= u_MeV;
m2 *= u_MeV;
m3 *= u_MeV;
m4 *= u_MeV;
double e1 = m1 + t1;
double e3 = m3 + t3;
ET = t1 + m1 + m2;
double p1 = TMath::Sqrt(t1*t1 + 2*m1*t1);
double p3 = TMath::Sqrt(t3*t3 + 2*m3*t3);
double cosTheta = TMath::Cos(angle3*TMath::Pi()/180.);
// return m1+m2-m3-TMath::Sqrt(m1*m1 + m2*m2 + m3*m3 + 2.*m2*e1 - 2.*e3*(e1+m2)+ 2.*p1*p3*cosTheta);
double Q = m1+m2-m3-TMath::Sqrt(m1*m1 + m2*m2 + m3*m3 + 2.*m2*e1 - 2.*e3*(e1+m2)+ 2.*p1*p3*cosTheta);
Qx = Q;
T4 = ET - e3 - (m1+m2-m3-Q);
//T4 = slowitdown("75Ga",T4,"1(12C)2(2H)",1.2);
P4 = TMath::Sqrt(T4*T4 + 2*m4*T4);
//this angle will not be affected by eloss
theta4 = (180./M_PI)*TMath::ASin((p3/P4)*TMath::Sin(angle3*M_PI/180.));
// T4-=16.5; //eloss in about 1.4 mg CD2
T4-=15.5; //eloss in 1.35 mg CD2 //TODO: actually degrade recoil/ejectiles in target
// T4-=14.1; //eloss in about 1.2 mg CD2
// T4-=31.7; //eloss in 2.7 mg CD2
//recalculate everything other than angle with lowered Kinetic energy
P4 = TMath::Sqrt(T4*T4 + 2*m4*T4);
gamma4 = T4/m4+1.;
beta4 = TMath::Sqrt(1. - 1./(gamma4*gamma4));
//beta4 = TMath::Sqrt((P4*P4)/(P4*P4 + m4*m4));
theta4 = (180./M_PI)*TMath::ASin((p3/P4)*TMath::Sin(angle3*M_PI/180.));
return Q0 - Q;//Q0 = Q + Exc
}
double Kinematics::getBeta4(double t3, double angle3)
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\return doppler-shift beta (=v/c) of the heavy-recoil nucleus, calls getExc() to fill the value
*/
{
getExc(t3, angle3);
return beta4;
}
double Kinematics::getBrho(double t3, double angle3, double charge_state) {
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\param charge_state charge state of the intended nucleus, in units of elementary charge (= +1 for H+, +2 for He2+ etc).
\return b-rho value, generated from P4*3.3359e-3/charge_state where P4 is 4momentum of heavy-recoil calculated from orruba kinematics
*/
getExc(t3,angle3);
return P4*3.3359e-3/charge_state;
}
double Kinematics::getTheta4(double t3, double angle3) {
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\param charge_state charge state of the intended nucleus, in units of elementary charge (= +1 for H+, +2 for He2+ etc).
\return lab theta value of heavy recoil in degrees
*/
getExc(t3,angle3);
return theta4;
}

207
Armory/Kinematics.h Normal file
View File

@ -0,0 +1,207 @@
#ifndef KINEMATICS_H
#define KINEMATICS_H
#include <TMath.h>
#include <iostream>
#include <fstream>
#include <string>
#include <TVector3.h>
const double u_MeV = 931.49410372; //u in MeV
class Kinematics {
public:
/*
A(d,p)B is used as template, with A being beam, and p being ejectile.
Always, make m3 the thing you detect, and m1 the beam
*/
double m_A, m_d, m_p, m_B;
double E_beam;
/**
* @{ \name List of funny impossible default values
*/
/**
* \brief Default values used for all the physics values
*/
double Q0=-9999, Qx=-9999;
double P4=-9999, E4=-9999, T4=-9999; //heavy recoil momentum, totE, KE
double P3=-9999, E3=-9999, T3=-9999; //light recoil
double ET=-9999;
double gamma4=-9999, beta4=-9999, theta4=-9999; //theta=heavy-recoil lab angle
double brho=-9999;
/**
* @}
*/
Kinematics(double m1, double m2, double m3, double m4, double ebeam) {
/*
A(d,p)B is used as template, with A being beam, and p being ejectile.
Always, make m3 the thing you detect, m2 the target, and m1 the beam
ebeam is in MeV/u, all others are in amu
*/
m_A = m1;
m_d = m2;
m_p = m3, m_B = m4, E_beam = ebeam*m_A;
Q0 = (- m_B - m_p + m_d + m_A)*u_MeV;
}
Kinematics() {}
void setValues(double m1, double m2, double m3, double m4, double ebeam) {
/*
Can be used to 'live update' say the beam energy in the case of active target detectors.
*/
m_A = m1;
m_d = m2;
m_p = m3, m_B = m4, E_beam = ebeam*m_A;
Q0 = (- m_B - m_p + m_d + m_A)*u_MeV;
//std::cout << "Q0 MeV: " << Q0 << std::endl;
}
void setEBeam(double Ebeam) {E_beam = Ebeam;}
double getBeta4(double t3, double angle3);
double getTheta4(double t3, double angle3);
double getBrho(double t3, double angle3, double charge_state);
double getExc(double t3, double angle3); //t3 is proton energy detected in ORRUBA, angle3 is proton angle in degrees
double getBeta4_fromvec(double t3, const TVector3 &pos, const TVector3 &origin) {
TVector3 local = pos - origin; //position w.r.t origin
float angle = local.Theta()*180./M_PI;
return getBeta4(t3, angle);
}
double getExc_fromvec(double t3, const TVector3 &pos, const TVector3 &origin) {
TVector3 local = pos - origin; //position w.r.t origin
float angle = local.Theta()*180./M_PI;
return getExc(t3, angle);
}
void setValuesFromFile(const std::string& filename) {
(void) filename;
/*std::ifstream in;
in.open(filename);
if(!in) {
std::cerr<< "File not open at " << filename << std::endl;
return;
}
for(std::string line; std::getline(in, line); ) {
if(line.size()!=0 && line[0]=='#')
; //don't do anything with '#' lines
else {
std::stringstream ss(line);
ss>>m_A>>m_d>>m_p>>m_B>>E_beam;
}
}
in.close();*/
}
};
//double Kinematics::getQval(double m1, double m2, double m3, double t1, double t3, double angle3)
double Kinematics::getExc(double t3, double angle3)
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
All calculations are done here, and other wrapper functions written make derived quantities from stuff calculated here.
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\return Excitation energy of the heavy-recoil nucleus in MeV
*/
{
double m1 = m_A;
double m2 = m_d;
double m3 = m_p;
double m4 = m_B;
double t1 = E_beam;
m1 *= u_MeV;
m2 *= u_MeV;
m3 *= u_MeV;
m4 *= u_MeV;
double e1 = m1 + t1;
double e3 = m3 + t3;
ET = t1 + m1 + m2;
double p1 = TMath::Sqrt(t1*t1 + 2*m1*t1);
double p3 = TMath::Sqrt(t3*t3 + 2*m3*t3);
double cosTheta = TMath::Cos(angle3*TMath::Pi()/180.);
// return m1+m2-m3-TMath::Sqrt(m1*m1 + m2*m2 + m3*m3 + 2.*m2*e1 - 2.*e3*(e1+m2)+ 2.*p1*p3*cosTheta);
double Q = m1+m2-m3-TMath::Sqrt(m1*m1 + m2*m2 + m3*m3 + 2.*m2*e1 - 2.*e3*(e1+m2)+ 2.*p1*p3*cosTheta);
Qx = Q;
//Recoil properties just in case it's useful
T4 = ET - e3 - (m1+m2-m3-Q);
P4 = TMath::Sqrt(T4*T4 + 2*m4*T4);
//this angle will not be affected by eloss
theta4 = (180./M_PI)*TMath::ASin((p3/P4)*TMath::Sin(angle3*M_PI/180.));
//recalculate everything other than angle with lowered Kinetic energy
P4 = TMath::Sqrt(T4*T4 + 2*m4*T4);
gamma4 = T4/m4+1.;
beta4 = TMath::Sqrt(1. - 1./(gamma4*gamma4));
theta4 = (180./M_PI)*TMath::ASin((p3/P4)*TMath::Sin(angle3*M_PI/180.));
return Q0 - Q;//Q0 = Q + Exc
}
double Kinematics::getBeta4(double t3, double angle3)
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\return doppler-shift beta (=v/c) of the heavy-recoil nucleus, calls getExc() to fill the value
*/
{
getExc(t3, angle3);
return beta4;
}
double Kinematics::getBrho(double t3, double angle3, double charge_state) {
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\param charge_state charge state of the intended nucleus, in units of elementary charge (= +1 for H+, +2 for He2+ etc).
\return b-rho value, generated from P4*3.3359e-3/charge_state where P4 is 4momentum of heavy-recoil calculated from orruba kinematics
*/
getExc(t3,angle3);
return P4*3.3359e-3/charge_state;
}
double Kinematics::getTheta4(double t3, double angle3) {
/*
\brief Follows convention in Marion, 2013: (1 - beam, 2- target, 3-ejectile, 4-recoil)
m1 is beam, (typically heavy nucleus)
m2 is 'd', (light target)
m3 is 'p', (light ejectile mass)
t1 is beam kinetic energy,
\param t3 lab-kinetic-energy in MeV
\param angle3 lab-angle in deg of detected proton (if d,p) or other charged particle
\param charge_state charge state of the intended nucleus, in units of elementary charge (= +1 for H+, +2 for He2+ etc).
\return lab theta value of heavy recoil in degrees
*/
getExc(t3,angle3);
return theta4;
}
#endif

674
Armory/LICENSE Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@ -10,7 +10,7 @@ COPTS = -fPIC -DLINUX -g -O0 -Wall -std=c++17 -lpthread
ROOTLIBS = `root-config --cflags --glibs` ROOTLIBS = `root-config --cflags --glibs`
ALL = Mapper AnasenMS ALL = Mapper EventBuilder#AnasenMS
######################################################################### #########################################################################
@ -23,6 +23,10 @@ Mapper : Mapper.cpp ../mapping.h ClassDet.h
@echo "--------- making Mapper" @echo "--------- making Mapper"
$(CC) $(COPTS) -o Mapper Mapper.cpp $(ROOTLIBS) $(CC) $(COPTS) -o Mapper Mapper.cpp $(ROOTLIBS)
AnasenMS : constant.h Isotope.h ClassTransfer.h ClassSX3.h ClassPW.h ClassAnasen.h anasenMS.cpp # AnasenMS : constant.h Isotope.h ClassTransfer.h ClassSX3.h ClassPW.h ClassAnasen.h anasenMS.cpp
@echo "--------- making ANASEN Monte Carlo" # @echo "--------- making ANASEN Monte Carlo"
$(CC) $(COPTS) -o AnasenMS anasenMS.cpp $(ROOTLIBS) # $(CC) $(COPTS) -o AnasenMS anasenMS.cpp $(ROOTLIBS)
EventBuilder : EventBuilder.cpp ClassData.h fsuReader.h Hit.h
@echo "--------- making EventBuilder"
$(CC) $(COPTS) -o EventBuilder EventBuilder.cpp $(ROOTLIBS)

View File

@ -11,12 +11,14 @@
#include "ClassDet.h" #include "ClassDet.h"
//=============================== //===============================
int main(int argc, char **argv){ int main(int argc, char **argv)
{
printf("=========================================\n"); printf("=========================================\n");
printf("=== Mapper ===\n"); printf("=== Mapper ===\n");
printf("=========================================\n"); printf("=========================================\n");
if (argc != 2) { if (argc != 2)
{
printf("Incorrect number of arguments:\n"); printf("Incorrect number of arguments:\n");
printf("%s [inFile]\n", argv[0]); printf("%s [inFile]\n", argv[0]);
printf("\n\n"); printf("\n\n");
@ -28,37 +30,37 @@ int main(int argc, char **argv){
PrintMapping(); PrintMapping();
TFile * inFile = new TFile(inFileName.c_str(), "READ"); TFile *inFile = new TFile(inFileName.c_str(), "READ");
TTree * tree = (TTree*) inFile->Get("tree"); TTree *tree = (TTree *)inFile->Get("tree");
unsigned long long totnumEntry = tree->GetEntries(); unsigned long long totnumEntry = tree->GetEntries();
ULong64_t evID; ULong64_t evID;
UInt_t multi; UInt_t multi;
UShort_t sn[MAXMULTI]; UShort_t sn[MAXMULTI];
UShort_t ch[MAXMULTI]; UShort_t ch[MAXMULTI];
UShort_t e[MAXMULTI]; UShort_t e[MAXMULTI];
UShort_t e2[MAXMULTI]; UShort_t e2[MAXMULTI];
ULong64_t e_t[MAXMULTI]; ULong64_t e_t[MAXMULTI];
UShort_t e_f[MAXMULTI]; UShort_t e_f[MAXMULTI];
tree->SetBranchAddress("evID", &evID); tree->SetBranchAddress("evID", &evID);
tree->SetBranchAddress("multi", &multi); tree->SetBranchAddress("multi", &multi);
tree->SetBranchAddress("sn", sn); tree->SetBranchAddress("sn", sn);
tree->SetBranchAddress("ch", ch); tree->SetBranchAddress("ch", ch);
tree->SetBranchAddress("e", e); tree->SetBranchAddress("e", e);
tree->SetBranchAddress("e2", e2); tree->SetBranchAddress("e2", e2);
tree->SetBranchAddress("e_t", e_t); tree->SetBranchAddress("e_t", e_t);
tree->SetBranchAddress("e_f", e_f); tree->SetBranchAddress("e_f", e_f);
///================== new tree ///================== new tree
TString outFileName = inFileName; TString outFileName = inFileName;
TString runStr = outFileName; TString runStr = outFileName;
int pos = outFileName.Last('/'); int pos = outFileName.Last('/');
pos = outFileName.Index("_", pos+1); // find next "_" pos = outFileName.Index("_", pos + 1); // find next "_"
runStr.Remove(0, pos+1); runStr.Remove(0, pos + 1);
runStr.Remove(3); runStr.Remove(3);
pos = outFileName.Index("_", pos+1); // find next "_" pos = outFileName.Index("_", pos + 1); // find next "_"
outFileName.Remove(pos); // remove the rest outFileName.Remove(pos); // remove the rest
outFileName += "_mapped.root"; outFileName += "_mapped.root";
ULong_t eventID; ULong_t eventID;
@ -66,117 +68,150 @@ int main(int argc, char **argv){
Det sx3; Det sx3;
Det qqq; Det qqq;
Det pc ; Det pc;
Det misc;
printf(" Raw root file : %s\n", inFileName.c_str()); printf(" Raw root file : %s\n", inFileName.c_str());
printf(" Run : %03d\n", run); printf(" Run : %03d\n", run);
printf(" total Entry : %lld \n", totnumEntry); printf(" total Entry : %lld \n", totnumEntry);
printf(" Out file name : %s \n", outFileName.Data()); printf(" Out file name : %s \n", outFileName.Data());
TFile * saveFile = new TFile( outFileName,"RECREATE"); TFile *saveFile = new TFile(outFileName, "RECREATE");
TTree * newTree = new TTree("tree","tree"); TTree *newTree = new TTree("tree", "tree");
newTree->Branch("evID", &eventID, "eventID/l");
newTree->Branch("evID", &eventID,"eventID/l"); newTree->Branch("run", &run, "run/i");
newTree->Branch("run", &run,"run/i");
newTree->Branch("sx3Multi", &sx3.multi, "sx3Multi/s"); newTree->Branch("sx3Multi", &sx3.multi, "sx3Multi/s");
newTree->Branch("sx3ID", &sx3.id, "sx3ID[sx3Multi]/s"); newTree->Branch("sx3ID", &sx3.id, "sx3ID[sx3Multi]/s");
newTree->Branch("sx3Ch", &sx3.ch, "sx3Ch[sx3Multi]/s"); newTree->Branch("sx3Ch", &sx3.ch, "sx3Ch[sx3Multi]/s");
newTree->Branch("sx3E", &sx3.e, "sx3Energy[sx3Multi]/s"); newTree->Branch("sx3E", &sx3.e, "sx3Energy[sx3Multi]/s");
newTree->Branch("sx3T", &sx3.t, "sx3Time[sx3Multi]/l"); newTree->Branch("sx3T", &sx3.t, "sx3Time[sx3Multi]/l");
newTree->Branch("qqqMulti", &qqq.multi, "qqqMulti/s"); newTree->Branch("qqqMulti", &qqq.multi, "qqqMulti/s");
newTree->Branch("qqqID", &qqq.id, "qqqID[qqqMulti]/s"); newTree->Branch("qqqID", &qqq.id, "qqqID[qqqMulti]/s");
newTree->Branch("qqqCh", &qqq.ch, "qqqCh[qqqMulti]/s"); newTree->Branch("qqqCh", &qqq.ch, "qqqCh[qqqMulti]/s");
newTree->Branch("qqqE", &qqq.e, "qqqEnergy[qqqMulti]/s"); newTree->Branch("qqqE", &qqq.e, "qqqEnergy[qqqMulti]/s");
newTree->Branch("qqqT", &qqq.t, "qqqTime[qqqMulti]/l"); newTree->Branch("qqqT", &qqq.t, "qqqTime[qqqMulti]/l");
newTree->Branch("qqqSN", &qqq.sn, "qqqSN[qqqMulti]/s"); newTree->Branch("qqqSN", &qqq.sn, "qqqSN[qqqMulti]/s");
newTree->Branch("pcMulti", &pc.multi, "pcMulti/s"); newTree->Branch("pcMulti", &pc.multi, "pcMulti/s");
newTree->Branch("pcID", &pc.id, "pcID[pcMulti]/s"); newTree->Branch("pcID", &pc.id, "pcID[pcMulti]/s");
newTree->Branch("pcCh", &pc.ch, "pcCh[pcMulti]/s"); newTree->Branch("pcCh", &pc.ch, "pcCh[pcMulti]/s");
newTree->Branch("pcE", &pc.e, "pcEnergy[pcMulti]/s"); newTree->Branch("pcE", &pc.e, "pcEnergy[pcMulti]/s");
newTree->Branch("pcT", &pc.t, "pcTime[pcMulti]/l"); newTree->Branch("pcT", &pc.t, "pcTime[pcMulti]/l");
newTree->Branch("miscMulti", &misc.multi, "miscMulti/s");
newTree->Branch("miscID", &misc.id, "miscID[miscMulti]/s");
newTree->Branch("miscCh", &misc.ch, "miscCh[miscMulti]/s");
newTree->Branch("miscE", &misc.e, "miscEnergy[miscMulti]/s");
newTree->Branch("miscT", &misc.t, "miscTime[miscMulti]/l");
newTree->Branch("miscF", &misc.tf, "miscFineTime[miscMulti]/l");
///================== looping old tree and apply mapping ///================== looping old tree and apply mapping
//clock // clock
// TBenchmark clock; // TBenchmark clock;
// Bool_t shown; // Bool_t shown;
for( unsigned long long ev = 0; ev < totnumEntry; ev++){ for (unsigned long long ev = 0; ev < totnumEntry; ev++)
{
tree->GetEntry(ev); tree->GetEntry(ev);
eventID = evID; eventID = evID;
sx3.multi = 0; sx3.multi = 0;
qqq.multi = 0; qqq.multi = 0;
pc.multi = 0; pc.multi = 0;
misc.multi = 0;
sx3.Clear();
sx3.Clear();
qqq.Clear(); qqq.Clear();
pc.Clear();
misc.Clear();
pc.Clear();
misc.Clear();
for( unsigned int i = 0; i < multi; i++){ for (unsigned int i = 0; i < multi; i++)
{
// printf("%10u/%10u| %5d, %2u, %6u, %14llu\n", i, multi, sn[i], ch[i], e[i], e_t[i] ); // printf("%10u/%10u| %5d, %2u, %6u, %14llu\n", i, multi, sn[i], ch[i], e[i], e_t[i] );
//globalCh = digi-ID * nCh(digi-iD) + ch // globalCh = digi-ID * nCh(digi-iD) + ch
int globalCh = -1; int globalCh = -1;
for( int j = 0; j < nBd; j++){ for (int j = 0; j < nBd; j++)
if( board.at(j) == sn[i]){ {
globalCh = (sn[i] > 1000 ? j * 64 : 7*64 + (j-7) * 16) + ch[i]; //& = number V1740 if (board.at(j) == sn[i])
{
globalCh = (sn[i] > 1000 ? j * 64 : 7 * 64 + (j - 7) * 16) + ch[i]; //& = number V1740
break; break;
} }
} }
if( globalCh == -1) printf("ev %llu\n", ev); if (globalCh == -1)
printf("ev %llu\n", ev);
unsigned short ID = mapping[globalCh]; unsigned short ID = mapping[globalCh];
//=================================== sx3 //=================================== sx3
if( ID < 10000 ) { if (ID < 10000)
{
sx3.id[sx3.multi] = ID / 100; sx3.id[sx3.multi] = ID / 100;
sx3.ch[sx3.multi] = ID % 100; sx3.ch[sx3.multi] = ID % 100;
sx3.e[sx3.multi] = e[i]; sx3.e[sx3.multi] = e[i];
sx3.t[sx3.multi] = e_t[i]; sx3.t[sx3.multi] = e_t[i];
sx3.multi ++; sx3.multi++;
} }
//=================================== qqq //=================================== qqq
if( 10000 <= ID && ID < 20000 ) { if (10000 <= ID && ID < 20000)
{
qqq.id[qqq.multi] = (ID - 10000) / 100; qqq.id[qqq.multi] = (ID - 10000) / 100;
qqq.ch[qqq.multi] = (ID - 10000) % 100; qqq.ch[qqq.multi] = (ID - 10000) % 100;
qqq.e[qqq.multi] = e[i]; qqq.e[qqq.multi] = e[i];
qqq.t[qqq.multi] = e_t[i]; qqq.t[qqq.multi] = e_t[i];
qqq.sn[qqq.multi] = sn[i]; qqq.sn[qqq.multi] = sn[i];
qqq.multi ++; qqq.multi++;
} }
//=================================== pc //=================================== pc
if( 20000 <= ID && ID < 30000 ) { if (20000 <= ID && ID < 30000)
{
pc.id[pc.multi] = (ID - 20000) / 100; pc.id[pc.multi] = (ID - 20000) / 100;
pc.ch[pc.multi] = (ID - 20000) % 100; pc.ch[pc.multi] = (ID - 20000) % 100;
pc.e[pc.multi] = e[i]; pc.e[pc.multi] = e[i];
pc.t[pc.multi] = e_t[i]; pc.t[pc.multi] = e_t[i];
pc.multi ++; pc.multi++;
}
//=================================== misc
if (30000 <= ID && ID < 40000)
{
misc.id[misc.multi] = (ID - 30000) / 100;
misc.ch[misc.multi] = (ID - 30000) % 100;
misc.e[misc.multi] = e[i];
misc.t[misc.multi] = e_t[i];
misc.tf[misc.multi] = e_f[i];
// if( ID == 30002 || ID == 30004 ) printf("sn : %d ch: %2d | gID %3d | ID %6d | e_f : %d\n", sn[i], ch[i], globalCh, ID, e_f[i]);
misc.multi++;
} }
} }
saveFile->cd(); //set focus on this file saveFile->cd(); // set focus on this file
newTree->Fill(); newTree->Fill();
if( eventID % 100 == 0 ) printf("%6lu/%6llu [%2d%%]\n\033[A\r", eventID, totnumEntry, TMath::Nint((eventID+1)*100./totnumEntry)); if (eventID % 100 == 0)
printf("%6lu/%6llu [%2d%%]\n\033[A\r", eventID, totnumEntry, TMath::Nint((eventID + 1) * 100. / totnumEntry));
} }
inFile->Close(); inFile->Close();
saveFile->cd(); //set focus on this file saveFile->cd(); // set focus on this file
newTree->Write(); newTree->Write();
UInt_t eventNumber = newTree->GetEntries(); UInt_t eventNumber = newTree->GetEntries();
saveFile->Close(); saveFile->Close();
printf("-------------- done, %u\n", eventNumber); printf("-------------- done, %u\n", eventNumber);
return 0; return 0;
} }

331
Armory/PCZRecon.h Normal file
View File

@ -0,0 +1,331 @@
#ifndef PCZRecon_h
#define PCZRecon_h
// PC Z-position reconstruction, one section per anode/cathode topology:
// A1C0 (single anode wire only), A2C0 (two-wire anode cluster, no cathode --
// same math as A1C0, see that section), A1C1 (anode + single cathode, charge
// division), A1C2 (anode + two cathodes, "step ladder" correction). Each topology gets one
// well-defined entry point instead of the math being split across files by
// historical accident (A1C0/A1C1 used to live in TrackRecon.C itself; A1C2's
// underlying model lives in the separately-shared PC_StepLadder_Correction.h
// -- see the A1C2 section below for why that one isn't just moved in).
//
// This header holds the reconstruction MATH only. The per-dataset tuning
// constants it reads (cfrac fit parameters, dead-wire lists, Z calibration,
// beam-axis origin) are still owned and set by TrackRecon.C's Begin() --
// this header just declares them `extern` so the same single translation
// unit (TrackRecon.C is compiled as one .C file via ACLiC) can see them.
// Moving the constants themselves out is a separate, riskier change and is
// deliberately NOT done here.
//
// Relocated verbatim from TrackRecon.C (no logic changes): A1C1CellSol,
// A1C1Sol, solve_cell, a1c1_solve, SideChoice, a1c1_pick_side, a1c1_zcorr,
// a1c0_hybrid_pcz (split into a1c0_wirePos + a1c0_hybrid_pcz).
//
// New in this header (see call-site migration notes where each is used):
// a1c1_solve_pick, a1c1_cfrac_pcz, a1c2_zfix.
#include <TVector3.h>
#include <TRandom3.h>
#include <TMath.h>
#include "ClassPW.h"
// --- Per-dataset tuning constants, defined and set in TrackRecon.C ---
extern PW pwinstance;
extern const double a1c1_zg[8];
extern double a1c1_cfmin_cell[7];
extern double a1c1_k_cell[7];
extern double a1c1_cfmin2_cell[7];
extern double a1c1_k2_cell[7];
extern double a1c1_cfrac_split;
extern double a1c1_lowband_rfactor;
extern double a1c1_missing_fmax;
extern double a1c1_z_scale_qqq;
extern double a1c1_z_off_qqq;
extern double a1c1_z_scale_sx3;
extern double a1c1_z_off_sx3;
bool a1c1_missing_neighbor(int awire, int cwire); // TrackRecon.C: dead-wire-adjacency check
TVector3 beamVertex(const TVector3 &si, const TVector3 &dir);
double beamPerp(const TVector3 &p);
// ---------------------------------------------------------------------
// A1C0: single-wire (anode only) position reconstruction
// ---------------------------------------------------------------------
// Anode-wire Z, corrected by the a1c1-derived scale+offset (a1c1_zcorr),
// same reference frame the a1c1 solve below reports in.
inline double a1c1_zcorr(double z_a1c0, bool isQQQ)
{
double scale = isQQQ ? a1c1_z_scale_qqq : a1c1_z_scale_sx3;
double off = isQQQ ? a1c1_z_off_qqq : a1c1_z_off_sx3;
return z_a1c0 * (1.0 - scale) - off;
}
// The raw (undithered) A1C0 wire position: nearest-wire XY at the given
// track phi, Z corrected into the same frame a1c1 uses. This is what
// _rawZ_a1c0 / phi cuts / _dPhi_a1c0-style diagnostics should read --
// anywhere you want the true discretized wire position, not a smoothed one.
inline TVector3 a1c0_wirePos(const std::pair<TVector3, TVector3> &apwire, double phi, bool isQQQ)
{
TVector3 pc = pwinstance.getClosestWirePosAtWirePhi(apwire, phi);
pc.SetZ(a1c1_zcorr(pc.Z(), isQQQ));
return pc;
}
// a1c0_wirePos, then Gaussian-dithered in Z to hide wire-pitch quantization.
// sigma is the caller's choice (dither_sigma or dither_sigma_c0/2.0 etc in
// TrackRecon.C) -- this function doesn't know which convention is "correct"
// for a given call site, only how to apply whichever sigma it's given.
inline TVector3 a1c0_hybrid_pcz(const std::pair<TVector3, TVector3> &apwire, double phi,
bool isQQQ, double sigma, TRandom3 &rand)
{
TVector3 pc = a1c0_wirePos(apwire, phi, isQQQ);
pc.SetZ(rand.Gaus(pc.Z(), sigma));
return pc;
}
// ---------------------------------------------------------------------
// A2C0: two-wire anode-cluster (charge-shared), no-cathode position
// reconstruction
// ---------------------------------------------------------------------
//
// Same math as A1C0 above -- pseudowire + phi-minimization, no dither --
// just handed a genuine 2-wire energy-weighted pseudowire (GetPseudoWire
// over a 2-wire anode cluster) instead of a single real wire. a1c0_wirePos
// already treats its `apwire` argument as an opaque pseudowire pair
// regardless of how many physical wires went into it, so this is a
// documented, named entry point rather than new math: call sites can say
// what topology they mean instead of reusing a1c0_wirePos silently and
// trusting a comment to explain why.
//
// Deliberately no dithered twin (no a2c0_hybrid_pcz): A2C0 is meant to feed
// the reaction-analysis plots at its raw, undithered resolution, not stand
// in for a1c0_hybrid_pcz's benchmark-truth-comparison role. If a "genuine
// A2C0" BenchMark validation block is ever wanted (mirroring the existing
// aClusters.size()==1 && cClusters.size()==0 A1C0 block in TrackRecon.C),
// add one there rather than adding dithering here.
inline TVector3 a2c0_wirePos(const std::pair<TVector3, TVector3> &apwire, double phi, bool isQQQ)
{
return a1c0_wirePos(apwire, phi, isQQQ);
}
// ---------------------------------------------------------------------
// A1C1: single-anode + single-cathode charge-division position reconstruction
// ---------------------------------------------------------------------
struct A1C1CellSol
{
int cell = -1;
double pcz = -99999;
double f = 0.0;
double pitch = 0.0;
bool inband = false;
bool pitchok = false;
};
struct A1C1Sol
{
int band;
double cfrac_used;
double pcz_lo;
double pcz_hi;
A1C1CellSol hi;
A1C1CellSol lo;
};
inline A1C1CellSol solve_cell(int cell, int wf, double zf, double cfrac,
const double *cfmin, const double *kk, bool dead_neighbor)
{
A1C1CellSol s;
s.cell = cell;
s.pcz = zf; // safe sentinel: fired-wire position so edge-wire defaults don't read as z=0
if (cell < 0 || cell > 6)
return s;
double zc = 0.5 * (a1c1_zg[cell] + a1c1_zg[cell + 1]); // cell centre
double half = 0.5 * (a1c1_zg[cell] - a1c1_zg[cell + 1]); // half-cell width
double pitch = a1c1_zg[cell] - a1c1_zg[cell + 1]; // full wire spacing
if (half <= 0.0 || kk[cell] <= 0.0)
return s;
s.pitch = pitch;
// f = 0 -> cell centre, f = 1 -> fired wire. Outside [0,1] = outside the band.
s.f = (cfrac - cfmin[cell]) / kk[cell];
// sign maps increasing f toward the fired cathode wire.
double sgn = (a1c1_zg[wf] >= zc) ? +1.0 : -1.0;
s.pcz = zc + sgn * s.f * half;
double fmax = dead_neighbor ? a1c1_missing_fmax : 1.0;
s.inband = (s.f >= 0.0 && s.f <= fmax);
// Reconstructed position should remain within one cell pitch of the fired wire.
s.pitchok = (TMath::Abs(s.pcz - zf) <= pitch);
return s;
}
inline A1C1Sol a1c1_solve(double cfrac, double zf, int cwire = -1, double anodeE = -1, int awire = -1)
{
A1C1Sol s{0, cfrac, zf, zf, {}, {}};
const double *cfmin = a1c1_cfmin_cell;
const double *kk = a1c1_k_cell;
if (a1c1_cfrac_split > 0.0 && cfrac >= 0.0 && cfrac < a1c1_cfrac_split)
{
s.band = 1;
if (a1c1_lowband_rfactor > 0.0 && cfrac > 0.0 && cfrac < 1.0)
{
double r = cfrac / (1.0 - cfrac);
r *= a1c1_lowband_rfactor;
cfrac = r / (1.0 + r);
}
else
{
cfmin = a1c1_cfmin2_cell;
kk = a1c1_k2_cell;
}
}
s.cfrac_used = cfrac;
int wf = 0;
for (int i = 1; i < 8; ++i)
if (TMath::Abs(a1c1_zg[i] - zf) < TMath::Abs(a1c1_zg[wf] - zf))
wf = i;
bool dead_neighbor = a1c1_missing_neighbor(awire, cwire); // same for both cells; hoist to avoid double scan
s.hi = solve_cell(wf - 1, wf, zf, cfrac, cfmin, kk, dead_neighbor); // cell above (higher z)
s.lo = solve_cell(wf, wf, zf, cfrac, cfmin, kk, dead_neighbor); // cell below (lower z)
s.pcz_hi = s.hi.pcz;
s.pcz_lo = s.lo.pcz;
return s;
}
// Which of the two candidate cells the beam-axis test selects.
enum class SideChoice
{
High, // the cell ABOVE the fired wire (pcz_hi)
Low // the cell BELOW the fired wire (pcz_lo)
};
// Picks between the two candidate cells (lo/hi) a1c1_solve returns.
//
// This used to compare beamVertex(si, ...)'s beamPerp for each candidate, but
// that check is a no-op: both candidates share the same (cx, cy), so
// beamVertex's t-parameter -- computed purely from dir.X()/dir.Y() -- comes out
// identical for both, and therefore so does the resulting vertex X/Y and
// beamPerp. The two disambiguating branches below were consequently dead code;
// the function always fell through to returning Low regardless of the actual
// physics.
//
// inband/pitchok DO differ between the two cells (each depends on cfrac's
// position within that cell's own band), so they're used here for status
// instead. The final tie-break prefers whichever candidate sits closer to the
// fired wire itself, rather than farther into the next cell over.
inline SideChoice a1c1_pick_side(const A1C1CellSol &lo, const A1C1CellSol &hi, double zf, int &status)
{
bool okl = lo.inband && lo.pitchok;
bool okh = hi.inband && hi.pitchok;
status = (okl || okh) ? ((okl && okh) ? 1 : 0) : 2;
if (okl && !okh)
return SideChoice::Low;
if (okh && !okl)
return SideChoice::High;
double dl = TMath::Abs(lo.pcz - zf);
double dh = TMath::Abs(hi.pcz - zf);
return (dl <= dh) ? SideChoice::Low : SideChoice::High;
}
// a1c1_solve() + a1c1_pick_side() together, with the picked cell already
// resolved. Every call site that needs more than just the final pcz (side
// status, cell index, f, inband, pitchok -- e.g. for benchmark/diagnostic
// histograms) was previously re-deriving this same 4-line pattern by hand;
// this is that pattern, named once.
struct A1C1PickedSol
{
A1C1Sol sol;
SideChoice side = SideChoice::Low;
int side_status = -1;
const A1C1CellSol &best() const { return (side == SideChoice::High) ? sol.hi : sol.lo; }
};
inline A1C1PickedSol a1c1_solve_pick(double cfrac, double zf, const TVector3 &si, double cx, double cy,
int cwire = -1, double anodeE = -1, int awire = -1)
{
// si/cx/cy are no longer used by the pick itself (see a1c1_pick_side above)
// but are kept in the signature so the ~10 existing call sites throughout
// TrackRecon.C don't need to change.
A1C1PickedSol out;
out.sol = a1c1_solve(cfrac, zf, cwire, anodeE, awire);
out.side = a1c1_pick_side(out.sol.lo, out.sol.hi, zf, out.side_status);
return out;
}
// Full pipeline: raw anode/cathode energies -> cfrac -> solve -> pick side ->
// picked Z, plus whether the pick landed in-band. This is what most call
// sites actually want (they don't need the intermediate A1C1Sol/side_status
// unless they're doing benchmark diagnostics -- for that, call
// a1c1_solve_pick directly instead).
//
// Takes primitives rather than TrackRecon.C's `Event` type so this header
// has no dependency on TrackRecon.C's class definitions; see the thin
// `Event`-taking overload kept in TrackRecon.C next to the `Event` class
// for the short call-site spelling existing code uses.
inline double a1c1_cfrac_pcz(double pcz_raw, double energyAnode, double energyCathode,
double cx, double cy, int cathodeCh, int anodeCh,
const TVector3 &si, bool &inband)
{
inband = false;
double ac = energyAnode + energyCathode;
double cfrac = (ac > 0.0) ? energyCathode / ac : -1.0;
if (cfrac < 0.0)
return pcz_raw;
A1C1PickedSol picked = a1c1_solve_pick(cfrac, pcz_raw, si, cx, cy, cathodeCh, energyAnode, anodeCh);
const A1C1CellSol &best = picked.best();
inband = (best.inband && picked.side_status != 2);
return best.pcz;
}
// ---------------------------------------------------------------------
// A1C2: two-cathode "step ladder" Z reconstruction
// ---------------------------------------------------------------------
//
// Same step-ladder, pivot-about-cell-midpoint model as Armory/
// PC_StepLadder_Correction.h's model_invert. That file is shared with
// MakeVertex.C (a separate, parallel branch of development, out of scope
// here) and a few scratch macros, so rather than include it or edit it,
// this is a standalone copy -- keeping every TrackRecon.C reconstruction
// path (A1C0/A1C1/A1C2) self-contained in this one header rather than
// reaching into a file with unrelated consumers. If the underlying model
// ever changes, both copies need the same edit; there are exactly two.
//
// Rewritten as a plain scalar function rather than kept in model_invert's
// original `double f(double *y, double *p)` shape -- that signature only
// existed to match TF1's raw-function-pointer constructor. TrackRecon.C
// used to go through a `TF1 pcfix_func` purely to get a callable out of it,
// calling only pcfix_func.Eval(z) at every site (npar `p` was never used,
// and nothing called .Draw()/.Integral()/anything else TF1-specific) --
// so the TF1 wrapper bought nothing. a1c2_zfix has the same scalar
// in/scalar out shape as a1c0_wirePos/a1c1_solve above instead.
inline double a1c2_zfix(double z)
{
double result = z;
double slope = 0.52;
double z_grid[8] = {148.2677, 102.1111, 59.8527, 19.7248, -19.7248, -59.8527, -102.1111, -148.2677};
for (int i = 0; i < 7; i++)
{
if (z <= z_grid[i] && z > z_grid[i + 1])
{
double zavg = (z_grid[i] + z_grid[i + 1]) * 0.5; // midpoint about which we pivot
result = (z - zavg) / slope + zavg;
break;
}
}
return result;
}
#endif

View File

@ -0,0 +1,82 @@
#include <TF1.h>
double model_invert(double *y, double *p)
{
double result = y[0];
double slope = 0.52;
double z_grid[8] = {147.998, 101.946, 59.7634, 19.6965, -19.6965, -59.7634, -101.946, -147.998};
for (int i = 0; i < 7; i++)
{
if (y[0] <= z_grid[i] && y[0] > z_grid[i + 1])
{
double zavg = (z_grid[i] + z_grid[i + 1]) * 0.5; // midpoint about which we pivot
result = (y[0] - zavg) / slope + zavg;
break;
}
}
return result;
}
// ---- Parabola variant (now takes optional slope; out-of-band -> Si, no clamp-snap) ----
inline double model_invert_a1c1(double cfrac, double z_si, double z_pivot,
double C, const double* c0_table, bool& ok,
double slope = 1.0)
{
ok = false;
static const double z_grid[8] =
{147.998, 101.946, 59.7634, 19.6965, -19.6965, -59.7634, -101.946, -147.998};
const double cfrac_hi = 0.90, cfrac_lo = 0.12;
if (cfrac > cfrac_hi || cfrac < cfrac_lo) return z_si;
const double sgn = (z_si >= z_pivot) ? +1.0 : -1.0;
int gnb = -1; double z_nb = (sgn > 0) ? +1.0e30 : -1.0e30;
for (int i = 0; i < 8; ++i) {
if (sgn > 0 && z_grid[i] > z_pivot + 1e-6 && z_grid[i] < z_nb) { z_nb = z_grid[i]; gnb = i; }
if (sgn < 0 && z_grid[i] < z_pivot - 1e-6 && z_grid[i] > z_nb) { z_nb = z_grid[i]; gnb = i; }
}
if (gnb < 0) return z_si;
const double W = TMath::Abs(z_nb - z_pivot);
if (W <= 0.0) return z_si;
int cell = (sgn > 0) ? gnb : gnb - 1;
if (cell < 0) cell = 0; if (cell > 6) cell = 6;
double s2 = (c0_table[cell] - cfrac) / C;
if (s2 < 0.0 || s2 > 1.0) return z_si; // out-of-band -> Si (no boundary snap)
double s = TMath::Sqrt(s2);
double z_rec = z_pivot + sgn * s * W;
if (slope > 0.0 && slope != 1.0) {
const double zc = 0.5 * (z_grid[cell] + z_grid[cell + 1]);
z_rec = (z_rec - zc) / slope + zc;
}
if (TMath::Abs(z_rec - z_si) > W) return z_si;
ok = true;
return z_rec;
}
// ---- Linear centre-fold variant ----
inline double model_invert_a1c1_linear(double cfrac, double z_si, double z_pivot,
double k, const double* cfmin_table, bool& ok)
{
ok = false;
static const double z_grid[8] =
{147.998, 101.946, 59.7634, 19.6965, -19.6965, -59.7634, -101.946, -147.998};
const double cfrac_hi = 0.90, cfrac_lo = 0.12;
if (cfrac > cfrac_hi || cfrac < cfrac_lo) return z_si;
int cell = -1;
for (int i = 0; i < 7; ++i)
if (z_si <= z_grid[i] && z_si > z_grid[i + 1]) { cell = i; break; }
if (cell < 0) return z_si;
const double zc = 0.5 * (z_grid[cell] + z_grid[cell + 1]);
const double half = 0.5 * (z_grid[cell] - z_grid[cell + 1]);
if (half <= 0.0 || k <= 0.0) return z_si;
double f = (cfrac - cfmin_table[cell]) / k;
if (f < 0.0) f = 0.0;
if (f > 1.0) return z_si;
const double d = f * half;
const double sgn = (z_pivot >= zc) ? +1.0 : -1.0;
const double z_rec = zc + sgn * d;
if (TMath::Abs(z_rec - z_si) > half) return z_si;
ok = true;
return z_rec;
}

190
Armory/SX3Geom.h Executable file
View File

@ -0,0 +1,190 @@
#ifndef SX3Geom_h
#define SX3Geom_h
#include <vector>
const double DEFAULT_NULL=-987654321.;
class sx3_geometry_scalefactors {
public:
//If sx3 has L, R being the left and right extremities, we choose add, stretch here such that
// x_mm = (x_raw+add)*stretch; so add=abs(L), stretch=75/(abs(L)+R)
float add[4];
float stretch[4];
};
class qqq5_finegains {
public:
std::array<std::pair<float,float>,32> front;
//front.at(30).first = slope at clkpos 0, ring 30 for E front layer
//front.at(30).second = intercept for the same as above
std::array<std::pair<float,float>,4> back;
};
class sx3_fbgains {
public:
//Order of indices is [pad][strip]
float padoffsets[4][4];
float padgains[4][4];
float stripLoffsets[4][4];
float stripLgains[4][4];
float stripRoffsets[4][4];
float stripRgains[4][4];
};
std::array<sx3_fbgains,24> sx3_xtalk_gains; //every sx3 needs to be gainmatched as a frontL-back, frontR-back pair (pad strip pair)
std::array<sx3_geometry_scalefactors,24> sx3gs;
class sx3 {
public:
//TODO: Convert to std::array
//Holds all information in an event, including ped subtraction+scaling. back[2].at(0) will have the largest energy seen in ch2, if any
std::vector<float> back[4];
std::vector<float> frontL[4];
std::vector<float> frontR[4];
double ts = DEFAULT_NULL;
//Easy lookup of final calibrated event. Only filled for valid cases, assumed for now to be 1L, 1R, 1B
float frontX=DEFAULT_NULL;
float frontXmm=DEFAULT_NULL;
float frontE=DEFAULT_NULL;
float backE=DEFAULT_NULL;
int stripF=DEFAULT_NULL;
int stripB=DEFAULT_NULL;
float frontEL=DEFAULT_NULL;
float frontER=DEFAULT_NULL;
float phi=DEFAULT_NULL; //
std::set<int> valid_front_chans;
std::set<int> valid_back_chans;
std::set<int> unmatched_front_chans; //every front channel is unmatched and invalid at first. when it gets matched, it gets removed and sent to valid
bool foundevent=false;
bool valid=false;//valid will be set to false in all cases where we have ambiguity
int flags=-1;//flags settable to different types of values to indicate different invalid situations
void fillevent(const std::string& position, const int subchannel, const float value); //make 'const' what functions don't need to change, helps with performance
void validate(const sx3_fbgains&, const sx3_geometry_scalefactors&);
void validate();
};
void sx3::fillevent(const std::string& positionstring, const int subchannel, const float value) {
assert(subchannel>=0 && subchannel<4);
foundevent=1;
if(positionstring=="FRONT_L") {
frontL[subchannel].push_back(value);
unmatched_front_chans.insert(subchannel);
} else if(positionstring=="FRONT_R") {
frontR[subchannel].push_back(value);
unmatched_front_chans.insert(subchannel);
} else if(positionstring=="BACK") {
back[subchannel].push_back(value);
valid_back_chans.insert(subchannel);
} else {
std::cout << "Unknown string "+positionstring+" encountered in sx3::fillevent \n" << std::endl;
}
if(frontL[subchannel].size()!=0 && frontR[subchannel].size()!=0 ) {
unmatched_front_chans.erase(subchannel);
valid_front_chans.insert(subchannel); //std::set, so no duplication will happen
}
}
//void sx3::validate(const sx3_fbgains& fbgains, const sx3_geometry_scalefactors& sx3gs) {
void sx3::validate() {
if(valid_front_chans.size()!=0 && valid_back_chans.size()!=0) {
valid=true;
float maxFE=0;
float maxBE=0;
//float zpos=0;
int bchan=-1;
int fchan=-1;
/* for(auto cc: valid_front_chans) {
std::cout << "fc" << cc << std::endl;// " " << frontL[cc].at(0) << " " << frontR[cc].at(0) << std::endl;
}
for(auto cc: valid_back_chans) {
std::cout << "bc" << cc << std::endl; //" " << back[cc].at(0) << std::endl;
}
*/
for(auto chan: valid_front_chans) {
if(frontL[chan].size()>1) {
printf("\nmultihit sx3 at Lsubchan:%d, ts:%1.13g\n",chan,ts);
for(const auto& e: frontL[chan]) printf("e: %f\t",e);
std::sort(frontL[chan].begin(), frontL[chan].end(), std::greater<float>());
flags += (-1000);
}
if(frontR[chan].size()>1) {
printf("\nmultihit sx3 at Rsubchan:%d, ts:%1.13g\n",chan,ts);
for(const auto& e: frontR[chan]) printf("e: %f\t",e);
std::sort(frontR[chan].begin(), frontR[chan].end(), std::greater<float>());
flags += (-2000);
}
//assign position using max L+R value
/*printf("chan:%d sizeL: %d sizeR: %d\n",chan, frontL[chan].size(), frontR[chan].size()); fflush(stdout);
printf("foo\n");
std::cout << "\nL:" << std::endl;
for(auto thing: frontL[chan]) std::cout << thing << " " << std::flush;
std::cout << "\nR:" << std::endl;
for(auto thing: frontR[chan]) std::cout << thing << " " << std::flush;*/
if(frontL[chan].at(0) + frontR[chan].at(0)>= maxFE) {
maxFE = frontL[chan].at(0) + frontR[chan].at(0);
//zpos = (frontL[chan].at(0)-frontR[chan].at(0))/maxFE;
fchan = chan;
}
}
for(auto chan: valid_back_chans) {
if(back[chan].size()>1) {
printf("\nmultihit sx3 at Bsubchan:%d, ts:%1.13g\n",chan,ts);
for(const auto& e: back[chan]) printf("e: %f\t",e);
std::sort(back[chan].begin(), back[chan].end(), std::greater<float>());
flags += (-3000);
}
if(back[chan].size() ==0 ) {
printf("foo\n");
//continue;
}
if(back[chan].at(0) >= maxBE) {
maxBE = back[chan].at(0);
bchan = chan;
}
}
/*
Cross-talk corrections are important when evaluating 'energy' signals from strips/pads.
They can cause unexpected behavior when used universally for all EL, ER cases, so we split scenarios in two.
- Positions along each strip (frontX) *are not* corrected for crosstalk.
- Total F and B energies (frontE, backE) *are*.
Sudarsan B, 31 Oct 2024
*/
if(fchan==-1 || bchan==-1) {
std::cout << "how" << std::endl;
std::cout << "fc " << std::flush; for(auto fc : valid_front_chans) std::cout << fc << " (" << frontL[fc].at(0) << "," << frontR[fc].at(0)<< ") "; std::cout << std::endl;
std::cout << "bc " << std::flush; for(auto bc : valid_back_chans) std::cout << bc << " " << back[bc].at(0) << std::flush; std::cout << std::endl;
}
float Eleft = frontL[fchan].at(0);
float Eright = frontR[fchan].at(0);
frontEL = Eleft;
frontER = Eright;
frontX = (Eleft-Eright)/(Eleft+Eright);
//frontXmm = (frontX+sx3gs.add[fchan])*sx3gs.stretch[fchan]; //convert to mm
//frontE = Eleft*fbgains.stripLgains[bchan][fchan] + fbgains.stripLoffsets[bchan][fchan]
// + Eright*fbgains.stripRgains[bchan][fchan] + fbgains.stripRoffsets[bchan][fchan];
//backE = back[bchan].at(0)*fbgains.padgains[bchan][fchan]+fbgains.padoffsets[bchan][fchan];
frontE = Eleft+Eright;
backE = maxBE;
stripF=fchan;
stripB=bchan;
flags = 0;
} else if(valid_front_chans.size()!=0 && valid_back_chans.size()==0) {
flags = -10;
} else if(valid_front_chans.size()==0 && valid_back_chans.size()!=0) {
flags = -20;
}
}
typedef sx3 sx3det;
#endif

795
Armory/fsuReader.h Normal file
View File

@ -0,0 +1,795 @@
#include "ClassData.h"
#include "Hit.h"
#include <algorithm>
#include <filesystem>
// #include "AggSeparator.h"
class FSUReader{
public:
FSUReader();
FSUReader(std::string fileName, uInt dataSize = 100, int verbose = 1);
FSUReader(std::vector<std::string> fileList, uInt dataSize = 100, int verbose = 1);
~FSUReader();
void OpenFile(std::string fileName, uInt dataSize, int verbose = 1);
bool IsOpen() const{return inFile == nullptr ? false : true;}
bool IsEndOfFile() const {
// printf("%s : %d | %ld |%ld\n", __func__, feof(inFile), ftell(inFile), inFileSize);
if(fileList.empty() ) {
if( (uLong )ftell(inFile) >= inFileSize){
return true;
}else{
return false;
}
}else{
if( fileID + 1 == (int) fileList.size() && ((uLong)ftell(inFile) >= inFileSize) ) {
return true;
}else{
return false;
}
}
}
void ScanNumBlock(int verbose = 1, uShort saveData = 0); // saveData = 0 (no save), 1 (no trace), 2 (with trace);
int ReadNextBlock(bool traceON = false, int verbose = 0, uShort saveData = 0); // saveData = 0 (no save), 1 (no trace), 2 (with trace);
int ReadBlock(unsigned int ID, int verbose = 0);
unsigned int GetFilePos() const {return filePos;}
unsigned long GetTotNumBlock() const{ return totNumBlock;}
std::vector<unsigned int> GetBlockTimestamp() const {return blockTimeStamp;}
Data * GetData() const{return data;}
std::string GetFileName() const{return fileName;}
int GetDPPType() const{return DPPType;}
int GetSN() const{return sn;}
int GetTick2ns() const{return tick2ns;}
int GetNumCh() const{return numCh;}
int GetFileOrder() const{return order;}
int GetChMask() const{return chMask;}
unsigned long GetFileByteSize() const {return inFileSize;}
void ClearHitList() { hit.clear();}
ulong GetHitListLength() const {return hit.size();}
std::vector<Hit> GetHitVector() const {return hit;}
void SortHit(int verbose = false);
Hit GetHit(int id) const {
if( id < 0 ) id = hit.size() + id;
return hit[id];
}
void ClearHitCount() {hitCount = 0;}
ulong GetHitCount() const{return hitCount;}
std::vector<Hit> ReadBatch(unsigned int batchSize = 1000000, bool verbose = false); // output the sorted Hit
// std::string SaveHit(std::vector<Hit> hitList, bool isAppend = false);
// std::string SaveHit2NewFile(std::string saveFolder = "./", std::string indexStr = "");
// void SortAndSaveTS(unsigned int batchSize = 1000000, bool verbose = false);
// off_t GetTSFileSize() const {return tsFileSize;}
//TODO
//void SplitFile(unsigned long hitSizePreFile);
void PrintHit(ulong numHit = -1, ulong startIndex = 0) {
for( ulong i = startIndex; i < std::min(numHit, hitCount); i++){
printf("%10zu ", i); hit[i].Print();
}
}
static void PrintHitListInfo(std::vector<Hit> * hitList, std::string name){
size_t n = hitList->size();
size_t s = sizeof(Hit);
printf("============== %s, size : %zu | %.2f MByte\n", name.c_str(), n, n*s/1024./1024.);
if( n > 0 ){
printf("t0 : %15llu ns\n", hitList->front().timestamp);
printf("t1 : %15llu ns\n", hitList->back().timestamp);
printf("dt : %15.3f ms\n", (hitList->back().timestamp - hitList->front().timestamp)/1e6);
}
}
void PrintHitListInfo(){
size_t n = hit.size();
size_t s = sizeof(Hit);
printf("============== reader.hit, size : %zu | %.2f MByte\n", n, n*s/1024./1024.);
if( n > 0 ){
printf("t0 : %15llu ns\n", hit.at(0).timestamp);
printf("t1 : %15llu ns\n", hit.back().timestamp);
printf("dt : %15.3f ms\n", (hit.back().timestamp - hit.front().timestamp)/1e6);
}
}
//void SaveAsCAENCoMPASSFormat();
private:
FILE * inFile;
Data * data;
std::string fileName;
std::vector<std::string> fileList;
short fileID;
unsigned long inFileSize;
unsigned int filePos;
unsigned long totNumBlock;
unsigned int blockID;
bool isDualBlock;
uShort sn;
uShort DPPType;
uShort tick2ns;
uShort order;
uShort chMask;
uShort numCh;
std::vector<unsigned int> blockPos;
std::vector<unsigned int > blockTimeStamp;
unsigned long hitCount;
std::vector<Hit> hit;
unsigned int word[1]; /// 4 byte
size_t dummy;
char * buffer;
off_t tsFileSize;
};
inline FSUReader::~FSUReader(){
delete data;
if( inFile ) fclose(inFile);
}
inline FSUReader::FSUReader(){
inFile = nullptr;
data = nullptr;
blockPos.clear();
blockTimeStamp.clear();
hit.clear();
fileList.clear();
fileID = -1;
}
inline FSUReader::FSUReader(std::string fileName, uInt dataSize, int verbose){
inFile = nullptr;
data = nullptr;
blockPos.clear();
blockTimeStamp.clear();
hit.clear();
fileList.clear();
fileID = -1;
OpenFile(fileName, dataSize, verbose);
}
inline FSUReader::FSUReader(std::vector<std::string> fileList, uInt dataSize, int verbose){
inFile = nullptr;
data = nullptr;
blockPos.clear();
blockTimeStamp.clear();
hit.clear();
//The files are the same DPPType and sn
this->fileList = fileList;
fileID = 0;
OpenFile(fileList[fileID], dataSize, verbose);
}
inline void FSUReader::OpenFile(std::string fileName, uInt dataSize, int verbose){
/// File format must be YYY...Y_runXXX_AAA_BBB_TT_CCC.fsu
/// YYY...Y = prefix
/// XXX = runID, 3 digits
/// AAA = board Serial Number, 3 digits
/// BBB = DPPtype, 3 digits
/// TT = tick2ns, any digits
/// CCC = over size index, 3 digits
if( inFile != nullptr ) fclose(inFile);
inFile = fopen(fileName.c_str(), "r");
if( inFile == NULL ){
printf("FSUReader::Cannot open file : %s \n", fileName.c_str());
this->fileName = "";
return;
}
this->fileName = fileName;
fseek(inFile, 0L, SEEK_END);
inFileSize = ftell(inFile);
if(verbose) printf("%s | file size : %ld Byte = %.2f MB\n", fileName.c_str() , inFileSize, inFileSize/1024./1024.);
fseek(inFile, 0L, SEEK_SET);
filePos = 0;
if( fileID > 0 ) return;
totNumBlock = 0;
blockID = 0;
blockPos.clear();
blockTimeStamp.clear();
hitCount = 0;
hit.clear();
//check is the file is *.fsu or *.fsu.X
size_t found = fileName.find_last_of('.');
std::string ext = fileName.substr(found + 1);
if( ext.find("fsu") != std::string::npos ) {
if(verbose > 1) printf("It is an raw data *.fsu format\n");
isDualBlock = false;
chMask = -1;
}else{
chMask = atoi(ext.c_str());
isDualBlock = true;
if(verbose > 1) printf("It is a splitted dual block data *.fsu.X format, dual channel mask : %d \n", chMask);
}
std::string fileNameNoExt;
found = fileName.find_last_of(".fsu");
size_t found2 = fileName.find_last_of('/');
if( found2 == std::string::npos ){
fileNameNoExt = fileName.substr(0, found-4);
}else{
fileNameNoExt = fileName.substr(found2+1, found-4);
}
// Split the string by underscores
std::istringstream iss(fileNameNoExt);
std::vector<std::string> tokens;
std::string token;
while (std::getline(iss, token, '_')) { tokens.push_back(token); }
sn = atoi(tokens[2].c_str());
tick2ns = atoi(tokens[4].c_str());
order = atoi(tokens[5].c_str());
DPPType = 0;
if( fileName.find("PHA") != std::string::npos ) DPPType = DPPTypeCode::DPP_PHA_CODE;
if( fileName.find("PSD") != std::string::npos ) DPPType = DPPTypeCode::DPP_PSD_CODE;
if( fileName.find("QDC") != std::string::npos ) DPPType = DPPTypeCode::DPP_QDC_CODE;
if( DPPType == 0 ){
fclose(inFile);
inFile = nullptr;
printf("Cannot find DPPType in the filename. Abort.");
return ;
}
numCh = (DPPType == DPPTypeCode::DPP_QDC_CODE ? 64 : 16);
data = new Data(numCh, dataSize);
data->tick2ns = tick2ns;
data->boardSN = sn;
data->DPPType = DPPType;
}
inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){
if( inFile == NULL ) return -1;
if( feof(inFile) || filePos >= inFileSize) {
if( fileID >= 0 && fileID + 1 < (short) fileList.size() ){
printf("-------------- next file\n");
fileID ++;
OpenFile(fileList[fileID], data->GetDataSize(), 1 );
}else{
return -1;
}
}
dummy = fread(word, 4, 1, inFile);
fseek(inFile, -4, SEEK_CUR);
if( dummy != 1) {
printf("fread error, should read 4 bytes, but read %ld x 4 byte, file pos: %ld / %ld byte\n",
dummy, ftell(inFile), inFileSize);
return -10;
}
short header = ((word[0] >> 28 ) & 0xF);
Hit temp;
if( header == 0xA ) { ///normal header
unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte
if( aggSize > inFileSize - ftell(inFile)) aggSize = inFileSize - ftell(inFile);
buffer = new char[aggSize];
dummy = fread(buffer, aggSize, 1, inFile);
filePos = ftell(inFile);
if( dummy != 1) {
printf("fread error, should read %d bytes, but read %ld x %d byte, file pos: %ld / %ld byte \n",
aggSize, dummy, aggSize, ftell(inFile), inFileSize);
return -30;
}
data->DecodeBuffer(buffer, aggSize, !traceON, verbose); // data will own the buffer
//printf(" word Index = %u | filePos : %u | ", data->GetWordIndex(), filePos);
}else if( (header & 0xF ) == 0x8 ) { /// dual channel header
unsigned int dualSize = (word[0] & 0x7FFFFFFF) * 4; ///byte
buffer = new char[dualSize];
dummy = fread(buffer, dualSize, 1, inFile);
filePos = ftell(inFile);
data->buffer = buffer;
data->DecodeDualBlock(buffer, dualSize, DPPType, chMask, !traceON, verbose);
}else{
printf("incorrect header.\n trminate.");
return -20;
}
unsigned int eventCout = 0;
for( int ch = 0; ch < data->GetNChannel(); ch++){
if( data->NumEventsDecoded[ch] == 0 ) continue;
hitCount += data->NumEventsDecoded[ch];
eventCout += data->NumEventsDecoded[ch];
if( saveData ){
int start = data->GetDataIndex(ch) - data->NumEventsDecoded[ch] + 1;
if( start < 0 ) start = start + data->GetDataSize();
for( int i = start; i < start + data->NumEventsDecoded[ch]; i++ ){
int k = i % data->GetDataSize();
temp.sn = sn;
temp.ch = ch;
temp.energy = data->GetEnergy(ch, k);
temp.energy2 = data->GetEnergy2(ch, k);
temp.timestamp = data->GetTimestamp(ch, k);
temp.fineTime = data->GetFineTime(ch, k);
temp.pileUp = data->GetPileUp(ch, k);
if( saveData > 1 ) {
temp.traceLength = data->Waveform1[ch][k].size();
temp.trace = data->Waveform1[ch][k];
}else{
temp.traceLength = 0;
if( temp.trace.size() > 0 ) temp.trace.clear();
}
hit.push_back(temp);
}
}
}
data->ClearTriggerRate();
data->ClearNumEventsDecoded();
data->ClearBuffer(); // this will clear the buffer.
return 0;
}
inline int FSUReader::ReadBlock(unsigned int ID, int verbose){
if( totNumBlock == 0 )return -1;
if( ID >= totNumBlock )return -1;
data->ClearData();
fseek( inFile, 0L, SEEK_SET);
if( verbose ) printf("Block index: %u, File Pos: %u byte\n", ID, blockPos[ID]);
fseek(inFile, blockPos[ID], SEEK_CUR);
filePos = blockPos[ID];
blockID = ID;
return ReadNextBlock(false, verbose, false);
}
inline void FSUReader::SortHit(int verbose){
if( verbose) printf("\nQuick Sort hit array according to time...");
std::sort(hit.begin(), hit.end(), [](const Hit& a, const Hit& b) {
return a.timestamp < b.timestamp;
});
if( verbose) printf(".......done.\n");
}
inline void FSUReader::ScanNumBlock(int verbose, uShort saveData){
if( inFile == nullptr ) return;
if( feof(inFile) ) return;
blockID = 0;
blockPos.push_back(0);
data->ClearData();
rewind(inFile);
filePos = 0;
bool isTraceOn = saveData < 2 ? false : true;
while( ReadNextBlock(isTraceOn, verbose - 1, saveData) == 0 ){
blockPos.push_back(filePos);
blockTimeStamp.push_back(data->aggTime);
blockID ++;
if(verbose && blockID % 10000 == 0) printf("%u, %.2f%% %u/%lu\n\033[A\r", blockID, filePos*100./inFileSize, filePos, inFileSize);
}
totNumBlock = blockID;
if(verbose) {
printf("\nScan complete: number of data Block : %lu\n", totNumBlock);
printf( " number of hit : %lu", hitCount);
if( hitCount > 1e6 ) printf(" = %.3f million", hitCount/1e6);
printf("\n");
if( saveData )printf( " size of the hit array : %lu\n", hit.size());
if( saveData ){
size_t sizeT = sizeof(hit[0]) * hit.size();
printf("size of hit array : %lu byte = %.2f kByte, = %.2f MByte\n", sizeT, sizeT/1024., sizeT/1024./1024.);
}
}
if( fileList.size() > 0 ){
fileID = 0;
OpenFile(fileList[fileID], data->GetDataSize(), 0);
}
rewind(inFile);
blockID = 0;
filePos = 0;
//check is the hitCount == hit.size();
if( saveData ){
if( hitCount != hit.size()){
printf("!!!!!! the Data::dataSize is not big enough. !!!!!!!!!!!!!!!\n");
}else{
SortHit(verbose+1);
}
}
}
inline std::vector<Hit> FSUReader::ReadBatch(unsigned int batchSize, bool verbose){
// printf("%s sn:%d. filePos : %lu\n", __func__, sn, ftell(inFile));
std::vector<Hit> hitList_A;
if( IsEndOfFile() ) {
hitList_A = hit;
hit.clear();
return hitList_A;
}
if( hit.size() == 0 ){
int res = 0;
do{
res = ReadNextBlock(true, 0, 3);
}while ( hit.size() < batchSize && res == 0);
SortHit();
uLong t0_B = hit.at(0).timestamp;
uLong t1_B = hit.back().timestamp;
if( verbose ) {
printf(" hit in memeory : %7zu | %u | %lu \n", hit.size(), filePos, inFileSize);
printf("t0 : %15lu ns\n", t0_B);
printf("t1 : %15lu ns\n", t1_B);
printf("dt : %15.3f ms\n", (t1_B - t0_B)/1e6);
}
hitList_A = hit;
hit.clear();
}else{
hitList_A = hit;
hit.clear();
}
if( IsEndOfFile() ) return hitList_A; // when file finished for 1st batch read
int res = 0;
do{
res = ReadNextBlock(true, 0, 3);
}while ( hit.size() < batchSize && res == 0);
SortHit();
uLong t0_B = hit.at(0).timestamp;
uLong t1_B = hit.back().timestamp;
if( verbose ) {
printf(" hit in memeory : %7zu | %u | %lu \n", hit.size(), filePos, inFileSize);
printf("t0 : %15lu\n", t0_B);
printf("t1 : %15lu\n", t1_B);
printf("dt : %15.3f ms\n", (t1_B - t0_B)/1e6);
}
uLong t0_A = hitList_A.at(0).timestamp;
uLong t1_A = hitList_A.back().timestamp;
ulong ID_A = 0;
ulong ID_B = 0;
if( t0_A >= t0_B) {
printf("\033[0;31m!!!!!!!!!!!!!!!!! %s | Need to increase the batch size. \033[0m\n", __func__);
return std::vector<Hit> ();
}
if( t1_A > t0_B) { // need to sort between two hitList
if( verbose ) {
printf("############# need to sort \n");
printf("=========== sume of A + B : %zu \n", hitList_A.size() + hit.size());
}
std::vector<Hit> hitTemp;
// find the hit that is >= t0_B, save them to hitTemp
for( size_t j = 0; j < hitList_A.size() ; j++){
if( hitList_A[j].timestamp < t0_B ) continue;;
if( ID_A == 0 ) ID_A = j;
hitTemp.push_back(hitList_A[j]);
}
// remove hitList_A element that is >= t0_B
hitList_A.erase(hitList_A.begin() + ID_A, hitList_A.end() );
// find the hit that is <= t1_A, save them to hitTemp
for( size_t j = 0; j < hit.size(); j++){
if( hit[j].timestamp > t1_A ) {
break;
}
hitTemp.push_back(hit[j]);
ID_B = j + 1;
}
// remove hit elements that is <= t1_A
hit.erase(hit.begin(), hit.begin() + ID_B );
// sort hitTemp
std::sort(hitTemp.begin(), hitTemp.end(), [](const Hit& a, const Hit& b) {
return a.timestamp < b.timestamp;
});
if( verbose ) {
printf("----------------- ID_A : %lu, Drop\n", ID_A);
printf("----------------- ID_B : %lu, Drop\n", ID_B);
PrintHitListInfo(&hitList_A, "hitList_A");
PrintHitListInfo(&hitTemp, "hitTemp");
PrintHitListInfo();
printf("=========== sume of A + B + Temp : %zu \n", hitList_A.size() + hit.size() + hitTemp.size());
printf("----------------- refill hitList_A \n");
}
for( size_t j = 0; j < hitTemp.size(); j++){
hitList_A.push_back(hitTemp[j]);
}
hitTemp.clear();
if( verbose ) {
PrintHitListInfo(&hitList_A, "hitList_A");
PrintHitListInfo();
printf("=========== sume of A + B : %zu \n", hitList_A.size() + hit.size());
}
}
return hitList_A;
}
/*
inline void FSUReader::SortAndSaveTS(unsigned int batchSize, bool verbose){
int count = 0;
std::vector<Hit> hitList_A ;
do{
if( verbose ) printf("***************************************************\n");
int res = 0;
do{
res = ReadNextBlock(true, 0, 3);
}while ( hit.size() < batchSize && res == 0);
SortHit();
uLong t0_B = hit.at(0).timestamp;
uLong t1_B = hit.back().timestamp;
if( verbose ) {
printf(" hit in memeory : %7zu | %u | %lu \n", hit.size(), filePos, inFileSize);
printf("t0 : %15lu\n", t0_B);
printf("t1 : %15lu\n", t1_B);
}
if( count == 0 ) {
hitList_A = hit; // copy hit
}else{
uLong t0_A = hitList_A.at(0).timestamp;
uLong t1_A = hitList_A.back().timestamp;
ulong ID_A = 0;
ulong ID_B = 0;
if( t0_A > t0_B) {
printf("Need to increase the batch size. \n");
return;
}
if( t1_A > t0_B) { // need to sort between two hitList
if( verbose ) {
printf("############# need to sort \n");
printf("=========== sume of A + B : %zu \n", hitList_A.size() + hit.size());
}
std::vector<Hit> hitTemp;
for( size_t j = 0; j < hitList_A.size() ; j++){
if( hitList_A[j].timestamp < t0_B ) continue;
if( ID_A == 0 ) ID_A = j;
hitTemp.push_back(hitList_A[j]);
}
hitList_A.erase(hitList_A.begin() + ID_A, hitList_A.end() );
if( verbose ) {
printf("----------------- ID_A : %lu, Drop\n", ID_A);
PrintHitListInfo(hitList_A, "hitList_A");
}
for( size_t j = 0; j < hit.size(); j++){
if( hit[j].timestamp > t1_A ) {
ID_B = j;
break;
}
hitTemp.push_back(hit[j]);
}
std::sort(hitTemp.begin(), hitTemp.end(), [](const Hit& a, const Hit& b) {
return a.timestamp < b.timestamp;
});
hit.erase(hit.begin(), hit.begin() + ID_B );
if( verbose ) {
PrintHitListInfo(hitTemp, "hitTemp");
printf("----------------- ID_B : %lu, Drop\n", ID_B);
PrintHitListInfo(hit, "hit");
printf("=========== sume of A + B + Temp : %zu \n", hitList_A.size() + hit.size() + hitTemp.size());
printf("----------------- refill hitList_A \n");
}
ulong ID_Temp = 0;
for( size_t j = 0; j < hitTemp.size(); j++){
hitList_A.push_back(hitTemp[j]);
if( hitList_A.size() >= batchSize ) {
ID_Temp = j+1;
break;
}
}
hitTemp.erase(hitTemp.begin(), hitTemp.begin() + ID_Temp );
for( size_t j = 0 ; j < hit.size(); j ++){
hitTemp.push_back(hit[j]);
}
SaveHit(hitList_A, count <= 1 ? false : true);
if( verbose ) {
PrintHitListInfo(hitList_A, "hitList_A");
PrintHitListInfo(hitTemp, "hitTemp");
printf("----------------- replace hitList_A by hitTemp \n");
}
hitList_A.clear();
hitList_A = hitTemp;
hit.clear();
if( verbose ) {
PrintHitListInfo(hitList_A, "hitList_A");
printf("===========================================\n");
}
}else{ // save hitList_A, replace hitList_A
SaveHit(hitList_A, count <= 1? false : true);
hitList_A.clear();
hitList_A = hit;
if( verbose ) PrintHitListInfo(hitList_A, "hitList_A");
}
}
ClearHitList();
count ++;
}while(filePos < inFileSize);
SaveHit(hitList_A, count <= 1 ? false : true);
printf("================= finished.\n");
}
*/
/*
inline std::string FSUReader::SaveHit(std::vector<Hit> hitList, bool isAppend){
std::string outFileName;
if( fileList.empty() ) {
outFileName = fileName + ".ts" ;
}else{
outFileName = fileList[0] + ".ts" ;
}
uint64_t hitSize = hitList.size();
FILE * outFile ;
if( isAppend ) {
outFile = fopen(outFileName.c_str(), "rb+"); //read/write bineary
rewind(outFile);
fseek( outFile, 4, SEEK_CUR);
uint64_t org_hitSize;
fread(&org_hitSize, 8, 1, outFile);
rewind(outFile);
fseek( outFile, 4, SEEK_CUR);
org_hitSize += hitSize;
fwrite(&org_hitSize, 8, 1, outFile);
fseek(outFile, 0, SEEK_END);
}else{
outFile = fopen(outFileName.c_str(), "wb"); //overwrite binary
uint32_t header = 0xAA000000;
header += sn;
fwrite( &header, 4, 1, outFile );
fwrite( &hitSize, 8, 1, outFile);
}
for( ulong i = 0; i < hitSize; i++){
if( i% 10000 == 0 ) printf("Saving %lu/%lu Hit (%.2f%%)\n\033[A\r", i, hitSize, i*100./hitSize);
uint16_t flag = hitList[i].ch + (hitList[i].pileUp << 8) ;
if( DPPType == DPPTypeCode::DPP_PSD_CODE ) flag += ( 1 << 15);
if( hitList[i].traceLength > 0 ) flag += (1 << 14);
// fwrite( &(hit[i].ch), 1, 1, outFile);
fwrite( &flag, 2, 1, outFile);
fwrite( &(hitList[i].energy), 2, 1, outFile);
if( DPPType == DPPTypeCode::DPP_PSD_CODE ) fwrite( &(hitList[i].energy2), 2, 1, outFile);
fwrite( &(hitList[i].timestamp), 6, 1, outFile);
fwrite( &(hitList[i].fineTime), 2, 1, outFile);
if( hitList[i].traceLength > 0 ) fwrite( &(hitList[i].traceLength), 2, 1, outFile);
for( uShort j = 0; j < hitList[i].traceLength; j++){
fwrite( &(hitList[i].trace[j]), 2, 1, outFile);
}
}
off_t tsFileSize = ftello(outFile); // unsigned int = Max ~4GB
fclose(outFile);
printf("Saved to %s, size: ", outFileName.c_str());
if( tsFileSize < 1024 ) {
printf(" %ld Byte", tsFileSize);
}else if( tsFileSize < 1024*1024 ) {
printf(" %.2f kB", tsFileSize/1024.);
}else if( tsFileSize < 1024*1024*1024){
printf(" %.2f MB", tsFileSize/1024./1024.);
}else{
printf(" %.2f GB", tsFileSize/1024./1024./1024.);
}
printf("\n");
return outFileName;
}
*/

56
Armory/macro.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef MACRO_H
#define MACRO_H
#define MaxNPorts 4 //for optical link
#define MaxNBoards 4 //for both optical link and usb
#define MaxNDigitizer MaxNPorts * MaxNBoards
#define MaxRegChannel 16
#define MaxNChannels 64
#define MaxRecordLength 0x3fff * 8
#define MaxSaveFileSize 1024 * 1024 * 1024 * 2
#define MaxDisplayTraceTimeLength 20000 //ns
#define ScopeUpdateMiliSec 200 // msec
#define MaxNumberOfTrace 5 // in an event
#define SETTINGSIZE 2048
#define DAQLockFile "DAQLock.dat"
#define PIDFile "pid.dat"
#include <sys/time.h> /** struct timeval, select() */
inline unsigned int getTime_us(){
unsigned int time_us;
struct timeval t1;
struct timezone tz;
gettimeofday(&t1, &tz);
time_us = (t1.tv_sec) * 1000 * 1000 + t1.tv_usec;
return time_us;
}
#include <chrono>
inline unsigned long long getTime_ns(){
std::chrono::high_resolution_clock::time_point currentTime = std::chrono::high_resolution_clock::now();
std::chrono::nanoseconds nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(currentTime.time_since_epoch());
return nanoseconds.count();
}
typedef unsigned short uShort;
typedef unsigned int uInt;
typedef unsigned long uLong;
typedef unsigned long long ullong;
#define DebugMode 0 //process check, when 1, print out all function call
// if DebugMode is 1, define DebugPrint() to be printf(), else, DebugPrint() define nothing
#if DebugMode
#define DebugPrint(fmt, ...) printf(fmt "::%s\n",##__VA_ARGS__, __func__);
#else
#define DebugPrint(fmt, ...)
#endif
#endif

File diff suppressed because it is too large Load Diff

6
BatchProcess.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/bash
#parallel -j 6 echo ./ProcessRun.sh {1} 2000 0 ::: {020..400}
parallel --jobs 1 --results log/log_{}.txt --memfree 1G --ctag -j 1 ./ProcessRun.sh {1} 2000 0 ::: {109..400} # for 17F
# parallel --results log/log_{}.txt --ctag -j 6 ./ProcessRun.sh {1} 4000 0 ::: {5..21}

45
CLAUDE.md Normal file
View File

@ -0,0 +1,45 @@
# ANASEN Analysis — working notes for Claude
## Agent behavior
- ALWAYS output a brief, step-by-step plan before modifying files or running commands.
- Commit only when explicitly asked. Do not push to remote on your own initiative; pushing is allowed only when the session's instructions name a branch to push to (e.g. a `claude/*` working branch), and never to `devel_vignesh` or any other shared branch.
- **Targeted edits only.** Never regenerate a whole file to make a local change.
- **Never read `MakeVertex.C`** (4,003 lines, 240 KB). Same rule as `TrackRecon.C` below if you must touch it: grep, then Read with offset/limit.
- **Never read `TrackRecon.C` end to end** (4,268 lines, 218 KB; ~60k tokens, and it stays in the prefix for the rest of the session). Grep for the symbol, then Read with offset/limit around the hit. If a question genuinely needs the whole file, say so first. Do not explore the codebase open-endedly.
- **Do not spawn subagents** for work that can be done inline — each starts cold and re-derives context already loaded. Worth it only for wide parallel searches where the conclusion is all that's needed.
- **You cannot verify your own work here.** No test suite, no CI, no data in the repo; validation is visual, via ROOT `TBrowser`, on a machine that has the data. Say explicitly when a change is unverified — never report a physics change as working because it compiled. The dangerous bugs are silent: a flipped sign in a kinematics term, an inverted spline direction, a wrong argument order, an off-by-one in a wire mask. None of them throw. The run completes, the plot renders, and the spectrum is wrong.
- **Review once per coherent change, not per edit.** Scale depth to blast radius: scratch macros, shell, and docs are shallow; `TrackRecon.C`, `MakeVertex.C`, `Armory/`, or any calibration fit is deep and should tolerate uncertain findings — silent failure is what's being hunted. Run `/security-review` only for file I/O or shell interpolation in the `run_*.sh` drivers; it is not a physics tool.
## Build & execution
- ROOT macros (`.C`) compile via ACLiC inside ROOT. Do not link into binaries.
- Standalone binaries (`EventBuilder`, `Mapper`): `cd Armory && make`
- Pre-compile for parallel runs: `root -q -l -b -e '.L TrackRecon.C++O'`
- Batch runs: `./run_17F.sh`, `./run_27Al.sh`, `./run_tr.sh`
- `run_tr.sh` gates its stages with `if [[ 1 -eq 0 ]]` / `if [[ 1 -eq 1 ]]`. Flip the literal to enable a block.
- Data is NOT in the repo. Mapped ROOT files live at `../ANASEN_analysis/data/${DATASET}_Data/${PREFIX}${run}_mapped.root`.
## Runtime configuration
All config is `getenv`-driven; the run scripts `export` it. Defaults are in `TrackRecon.C::Begin()`.
Physics / results-affecting:
`DATASET` `reactiondata` `CO2percent` `pressure_in_torr` `CATHODE_GAIN` `PC_ENERGY_CALIBRATION`
`source_vertex` `CUTLIST` `DITHER_SIGMA` `RNG_SEED` `BEAM_AXIS_X` `BEAM_AXIS_Y`
`timecut_low` `timecut_high` `DISABLE_BAD_ANODE_WIRES` `A1C1_LOWBAND_RFACTOR`
`A1C1_Z_SCALE_QQQ` `A1C1_Z_SCALE_SX3` `A1C1_Z_OFF_QQQ` `A1C1_Z_OFF_SX3`
Plumbing: `OUT_DIR` `RUN_NUMBER` `FLUSH_BARRIER` `MAX_RSS_MB` `MEMCHECK_STRIDE`
**`DEDX_SCALE` is read by `eloss_calculations/Eloss.py`, NOT by `TrackRecon.C`.**
It multiplies `catima.dedx` when the lookup tables are generated. Changing it invalidates every `.dat` table — re-run `Eloss.py` (the run scripts do this automatically before processing). Tables are keyed `eloss_calculations/<species>_lookup_<E>MeV_<P>torr_<CO2>pc.dat` (e.g. `alpha_lookup_50MeV_250torr_3pc.dat`).
## Footguns
- **`HistPlotter` keys `oMap` by histogram NAME only.** The folder argument does not namespace. Two `Fill` calls with the same name and the *same* folder merge silently — no warning, no error, wrong plot. A same-name/different-folder (or toplevel-vs-folder) clash does print to `stderr` and then merges anyway, but the run scripts send stdout+stderr to `/dev/null`, so in a batch run it is invisible either way. Always make names unique.
- **Si–PC coincidence sits at negative dt.** The band is centred well below zero, not near it. The one gate of record is `siPcCoincident()` in `TrackRecon.C` (`kSiPcDtMin = -500`, `kSiPcDtMax = 150` ns); anything else is a plotting range, not a cut. Do not "correct" a timing gate toward zero.
- **RNG**: in `TrackRecon.C`, one shared `anasenRandom` (`TRandom3`, seed 4357, `RNG_SEED` to override), aliased by reference wherever a local `rnd`/`rand` appears — do not introduce fresh `TRandom3(0)` instances; it breaks reproducibility. `MakeVertex.C` predates this and still has ~12 independent default-seeded `TRandom3` objects; do not assume its output is reproducible against `TrackRecon.C`.
- **Pass By Reference in Event Loops:** Always iterate via `const auto&` over cluster/hit vectors to prevent expensive struct copies in multi-million event runs.
## Invariants to check on any physics change
Units (MeV vs keV, cm vs mm); sign conventions on `z` and beam direction; eloss spline domain and extrapolation; energy conservation in the kinematics; dead-wire / neighbour masking; RNG seeding. When reviewing, include the `.dat` and `run_*.sh` parameter deltas — the most consequential recent changes have been constants, not code.
## Docs
`README.md` has the pipeline documentation and full file references.

270
CalibrationQQQ.C Normal file
View File

@ -0,0 +1,270 @@
#define CalibrationQQQ_cxx
#include <TH2.h>
#include <TF1.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TMath.h>
#include <TCutG.h>
#include <fstream>
#include <utility>
#include <algorithm>
#include "Armory/HistPlotter.h"
#include "TVector3.h"
#include "Calibration.h"
TH2F *hQQQFVB;
HistPlotter *plotter;
int padID = 0;
TCutG *cut;
std::map<std::tuple<int, int, int>, std::vector<std::pair<double, double>>> dataPoints;
bool qqqEcut = false;
// Gain Arrays
const int MAX_QQQ = 4;
const int MAX_RING = 16;
const int MAX_WEDGE = 16;
double qqqwGain[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
// double qqqrGain[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
bool qqqwGainValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
// bool qqqrGainValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
void CalibrationQQQ::Begin(TTree * /*tree*/)
{
plotter = new HistPlotter("Calib.root", "TFILE");
// ----------------------- Load QQQ Gains
{
std::string filename = "qqq_GainMatch.dat";
std::ifstream infile(filename);
if (!infile.is_open())
{
std::cerr << "Error opening " << filename << "!" << std::endl;
}
else
{
int det, ring, wedge;
double gainw, gainr;
while (infile >> det >> ring >> wedge >> gainw >> gainr)
{
qqqwGain[det][ring][wedge] = gainw;
// qqqrGain[det][ring][wedge] = gainr;
qqqwGainValid[det][ring][wedge] = (gainw > 0);
// qqqrGainValid[det][ring][wedge] = (gainr > 0);
}
infile.close();
std::cout << "Loaded QQQ gains from " << filename << std::endl;
}
}
for (int det = 0; det < MAX_QQQ; det++)
{
for (int ring = 0; ring < MAX_RING; ring++)
{
for (int wedge = 0; wedge < MAX_WEDGE; wedge++)
{
TString hname = Form("hCal_qqq%d_ring%d_wedge%d", det, ring, wedge);
TString htitle = Form("QQQ det%d ring%d wedge%d; Energy (arb); Counts", det, ring, wedge);
// hQQQSpectra[det][ring][wedge] = new TH1F(hname, htitle, 4000, 0, 16000);
}
}
}
}
Bool_t CalibrationQQQ::Process(Long64_t entry)
{
b_qqqMulti->GetEntry(entry);
b_qqqID->GetEntry(entry);
b_qqqCh->GetEntry(entry);
b_qqqE->GetEntry(entry);
b_qqqT->GetEntry(entry);
qqq.CalIndex();
for (int i = 0; i < qqq.multi; i++)
{
for (int j = i + 1; j < qqq.multi; j++)
{
if (qqq.e[i] > 100)
qqqEcut = true;
if (qqq.id[i] == qqq.id[j])
{
int chWedge = -1;
int chRing = -1;
float eWedgeRaw = 0.0;
float eWedge = 0.0;
float eRingRaw = 0.0;
float eRing = 0.0;
if (qqq.ch[i] < 16 && qqq.ch[j] >= 16 && /*qqqrGainValid[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16] &&*/ qqqwGainValid[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16])
{
chWedge = qqq.ch[i];
eWedgeRaw = qqq.e[i];
eWedge = qqq.e[i] * qqqwGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16];
// printf("Wedge E: %.2f Gain: %.4f \n", eWedge, qqqGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16]);
chRing = qqq.ch[j] - 16;
eRingRaw = qqq.e[j];
eRing = qqq.e[j];// * qqqrGain[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16];
}
else if (qqq.ch[j] < 16 && qqq.ch[i] >= 16 && /*qqqrGainValid[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16] &&*/ qqqwGainValid[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16])
{
chWedge = qqq.ch[j];
eWedge = qqq.e[j] * qqqwGain[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16];
eWedgeRaw = qqq.e[j];
chRing = qqq.ch[i] - 16;
eRing = qqq.e[i];// * qqqrGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16];
eRingRaw = qqq.e[i];
}
else
continue;
// hQQQFVB->Fill(eWedge, eRing);
plotter->Fill2D(Form("hRaw_qqq%d_ring%d_wedge%d", qqq.id[i], chRing, chWedge), 400, 0, 16000, 400, 0, 16000, eWedgeRaw, eRingRaw, "ERaw");
plotter->Fill2D(Form("hGM_qqq%d_ring%d_wedge%d", qqq.id[i], chRing, chWedge), 400, 0, 16000, 400, 0, 16000, eWedge, eRing, "EGM");
plotter->Fill2D("hRawQQQ", 4000, 0, 16000, 4000, 0, 16000, eWedgeRaw, eRingRaw);
plotter->Fill2D("hGMQQQ", 4000, 0, 16000, 4000, 0, 16000, eWedge, eRing);
TString histName = Form("hQQQFVB_id%d_r%d_w%d", qqq.id[i], chRing, chWedge);
// TH2F *hist2d = (TH2F *)gDirectory->Get(histName);
// if (!hist2d)
// {
// hist2d = new TH2F(histName, Form("QQQ Det%d R%d W%d;Wedge E;Ring E", qqq.id[i], chRing, chWedge), 400, 0, 16000, 400, 0, 16000);
// }
// hist2d->Fill(eWedge, eRing);
// if (cut && cut->IsInside(eWedge, eRing))
const double MIN_ADC = 1500.0;
const double MAX_ADC = 3000.0;
// if (eWedge >= MIN_ADC && eWedge <= MAX_ADC &&
// eRing >= MIN_ADC && eRing <= MAX_ADC)
double ratio = (eWedge > 0.0) ? (eRing / eWedge) : 0.0;
double maxslope = 1.5;
bool validPoint = false;
if (ratio < maxslope && ratio > 1. / maxslope)
{
// Accumulate data for gain matching
dataPoints[{qqq.id[i], chRing, chWedge}].emplace_back(eWedge, eRing);
}
}
}
}
return kTRUE;
}
void CalibrationQQQ::Terminate()
{
const double AM241_PEAK = 5485.56;
const double P_PEAK = 7000; // keV
double calibArray[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
bool calibValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
std::ofstream outFile("qqq_Calib.dat");
if (!outFile.is_open())
{
std::cerr << "Error opening qqq_Calib.dat!" << std::endl;
return;
}
//----------------------------------------------------------------------
// 1. Create per–channel 1D spectra in ADC from stored gain-matched data
//----------------------------------------------------------------------
std::map<std::tuple<int, int, int>, TH1F *> spectra;
for (auto &kv : dataPoints)
{
int det, ring, wedge;
std::tie(det, ring, wedge) = kv.first;
TString hname = Form("hSpec_d%d_r%d_w%d", det, ring, wedge);
TH1F *h = new TH1F(hname, hname, 4000, 0, 16000);
for (auto &p : kv.second)
{
double eWedge = p.first; // already gain-matched ADC
double eRing = p.second;
// Use ring ADC for calibration (cleaner alpha peak)
h->Fill(eRing);
}
spectra[kv.first] = h;
}
//----------------------------------------------------------------------
// 2. Fit Am-241 peak and extract keV/ADC calibration slope
//----------------------------------------------------------------------
for (auto &kv : spectra)
{
int det, ring, wedge;
std::tie(det, ring, wedge) = kv.first;
TH1F *h = kv.second;
if (!h || h->GetEntries() < 50)
continue;
int binMax = h->GetMaximumBin();
double adcPeak = h->GetXaxis()->GetBinCenter(binMax);
if (adcPeak <= 0)
continue;
double slope_keV = AM241_PEAK / adcPeak; // keV per ADC
// double slope_keV = P_PEAK / adcPeak; // keV per ADC
calibArray[det][ring][wedge] = slope_keV;
calibValid[det][ring][wedge] = true;
outFile << det << " " << wedge << " " << ring << " "
<< slope_keV << "\n";
// printf("QQQ DET=%d R=%d W=%d ADCpeak=%.1f slope_keV=%.6f\n",det, ring, wedge, adcPeak, slope_keV);
}
outFile.close();
std::cout << "Wrote QQQ calibration file qqq_Calib.dat\n";
//----------------------------------------------------------------------
// 3. Build fully calibrated 2D combined histogram
//----------------------------------------------------------------------
TH2F *hCal = new TH2F("hCal",
"All QQQ Calibrated;Wedge Energy (keV);Ring Energy (keV)",
800, 0, 7000,
800, 0, 7000);
for (auto &kv : dataPoints)
{
int det, ring, wedge;
std::tie(det, ring, wedge) = kv.first;
if (!calibValid[det][ring][wedge])
continue;
double slope = calibArray[det][ring][wedge];
for (auto &p : kv.second)
{
double eWGM = p.first; // gain matched ADC
double eRGM = p.second;
double eWkeV = eWGM * slope / 1000;
double eRkeV = eRGM * slope / 1000;
hCal->Fill(eWkeV, eRkeV);
plotter->Fill2D("hCalQQQ", 4000, 0, 10, 4000, 0, 10, eWkeV, eRkeV);
plotter->Fill2D(Form("hRCal_qqq%d", det), 16, 0, 15, 400, 0, 24, ring, eRkeV, "RingCal");
plotter->Fill2D(Form("hWCal_qqq%d", det), 16, 0, 15, 400, 0, 24, wedge, eWkeV, "WedgeCal");
}
}
plotter->FlushToDisk();
std::cout << "Calibrated 2D QQQ histogram saved.\n";
}

114
CalibrationQQQ.h Normal file
View File

@ -0,0 +1,114 @@
#ifndef CalibrationQQQ_h
#define CalibrationQQQ_h
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TSelector.h>
#include "Armory/ClassDet.h"
class CalibrationQQQ : public TSelector {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
// Fixed size dimensions of array or collections stored in the TTree if any.
// Declaration of leaf types
Det sx3;
Det qqq;
Det pc ;
ULong64_t evID;
UInt_t run;
// List of branches
TBranch *b_eventID; //!
TBranch *b_run; //!
TBranch *b_sx3Multi; //!
TBranch *b_sx3ID; //!
TBranch *b_sx3Ch; //!
TBranch *b_sx3E; //!
TBranch *b_sx3T; //!
TBranch *b_qqqMulti; //!
TBranch *b_qqqID; //!
TBranch *b_qqqCh; //!
TBranch *b_qqqE; //!
TBranch *b_qqqT; //!
TBranch *b_pcMulti; //!
TBranch *b_pcID; //!
TBranch *b_pcCh; //!
TBranch *b_pcE; //!
TBranch *b_pcT; //!
CalibrationQQQ(TTree * /*tree*/ =0) : fChain(0) { }
virtual ~CalibrationQQQ() { }
virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree);
virtual void Init(TTree *tree);
virtual Bool_t Notify();
virtual Bool_t Process(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
virtual void SetOption(const char *option) { fOption = option; }
virtual void SetObject(TObject *obj) { fObject = obj; }
virtual void SetInputList(TList *input) { fInput = input; }
virtual TList *GetOutputList() const { return fOutput; }
virtual void SlaveTerminate();
virtual void Terminate();
ClassDef(CalibrationQQQ,0);
};
#endif
#ifdef CalibrationQQQ_cxx
void CalibrationQQQ::Init(TTree *tree){
// Set branch addresses and branch pointers
if (!tree) return;
fChain = tree;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("evID", &evID, &b_eventID);
fChain->SetBranchAddress("run", &run, &b_run);
sx3.SetDetDimension(24,12);
qqq.SetDetDimension(4,32);
pc.SetDetDimension(2,24);
fChain->SetBranchAddress("sx3Multi", &sx3.multi, &b_sx3Multi);
fChain->SetBranchAddress("sx3ID", &sx3.id, &b_sx3ID);
fChain->SetBranchAddress("sx3Ch", &sx3.ch, &b_sx3Ch);
fChain->SetBranchAddress("sx3E", &sx3.e, &b_sx3E);
fChain->SetBranchAddress("sx3T", &sx3.t, &b_sx3T);
fChain->SetBranchAddress("qqqMulti", &qqq.multi, &b_qqqMulti);
fChain->SetBranchAddress("qqqID", &qqq.id, &b_qqqID);
fChain->SetBranchAddress("qqqCh", &qqq.ch, &b_qqqCh);
fChain->SetBranchAddress("qqqE", &qqq.e, &b_qqqE);
fChain->SetBranchAddress("qqqT", &qqq.t, &b_qqqT);
fChain->SetBranchAddress("pcMulti", &pc.multi, &b_pcMulti);
fChain->SetBranchAddress("pcID", &pc.id, &b_pcID);
fChain->SetBranchAddress("pcCh", &pc.ch, &b_pcCh);
fChain->SetBranchAddress("pcE", &pc.e, &b_pcE);
fChain->SetBranchAddress("pcT", &pc.t, &b_pcT);
}
Bool_t CalibrationQQQ::Notify(){
return kTRUE;
}
void CalibrationQQQ::SlaveBegin(TTree * /*tree*/){
TString option = GetOption();
}
void CalibrationQQQ::SlaveTerminate(){
}
#endif // #ifdef CalibrationQQQ_cxx

View File

@ -0,0 +1,124 @@
#include <TFile.h>
#include <TH1.h>
#include <TSpectrum.h>
#include <TF1.h>
#include <TCanvas.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <fstream>
#include <TText.h>
void FitHistogramsWithTSpectrum_Sequential_Improved() {
TFile *inputFile = new TFile("Histograms_anodes.root", "READ");
if (!inputFile || inputFile->IsZombie()) {
std::cerr << "Error opening the input file!" << std::endl;
return;
}
TCanvas *c1 = new TCanvas("c1", "Histogram Viewer", 800, 600);
// Open the output ASCII file to save the centroids
std::ofstream outFile("centroids.txt");
if (!outFile.is_open()) {
std::cerr << "Error opening output file!" << std::endl;
return;
}
outFile << "HistogramIndex\tPeakNumber\tCentroid\tAmplitude\tSigma" << std::endl;
for (int i = 0; i < 24; ++i) {
TH1 *histogram = dynamic_cast<TH1*>(inputFile->Get(Form("hCathode_%d", i)));
if (!histogram) {
std::cerr << "Failed to retrieve histogram_" << i << " from the file." << std::endl;
continue;
}
// Set range for peak search
double minX = 700;
double maxX = 25000;
histogram->GetXaxis()->SetRangeUser(minX, maxX);
// Draw the histogram
c1->cd();
histogram->Draw();
// Peak search using TSpectrum
const int maxPeaks = 5;
TSpectrum spectrumFinder(maxPeaks);
int nFound = spectrumFinder.Search(histogram, 2, "", 0.01);
if (nFound <= 0) {
std::cerr << "No peaks found for histogram " << i << std::endl;
continue;
}
Double_t *xPositions = spectrumFinder.GetPositionX();
Double_t *yPositions = spectrumFinder.GetPositionY();
std::vector<std::pair<Double_t, Double_t>> peaks;
// Collect and sort peaks by X position
for (int j = 0; j < nFound; ++j) {
peaks.emplace_back(xPositions[j], yPositions[j]);
}
std::sort(peaks.begin(), peaks.end());
// Fit each peak with a Gaussian
for (int j = 0; j < peaks.size(); ++j) {
Double_t peakX = peaks[j].first;
Double_t peakY = peaks[j].second;
Double_t initialAmplitude = peakY; // Better initial guess
Double_t initialCentroid = peakX; // Centroid based on peak position
Double_t initialSigma = 60.0;
// Define Gaussian with initial parameters
TF1 *gaussFit = new TF1(Form("gauss_%d", j), "gaus", peakX - 200, peakX + 200);
//gaussFit->SetParameters(peakY, peakX, 25.0); // Initial guesses for amplitude, mean, sigma
gaussFit->SetParameters(initialAmplitude, initialCentroid, initialSigma);
// Perform fit
int fitStatus = histogram->Fit(gaussFit, "RQ+");
if (fitStatus != 0) {
std::cerr << "Fit failed for peak " << j + 1 << " in histogram " << i << std::endl;
delete gaussFit;
continue;
}
// Retrieve fit parameters
double amplitude = gaussFit->GetParameter(0);
double centroid = gaussFit->GetParameter(1);
double sigma = gaussFit->GetParameter(2);
double amplitudeError = gaussFit->GetParError(0);
double centroidError = gaussFit->GetParError(1);
double sigmaError = gaussFit->GetParError(2);
// Chi-squared value
double chi2 = gaussFit->GetChisquare();
int ndf = gaussFit->GetNDF();
outFile << i << "\t" << j + 1 << "\t" << centroid << std::endl;
gaussFit->SetLineColor(kRed);
gaussFit->Draw("SAME");
TText *text = new TText();
text->SetNDC();
text->SetTextSize(0.03);
text->SetTextColor(kRed);
//text->DrawText(0.15, 0.8 - j * 0.05, Form("Peak %d: Amp=%.2f, Mean=%.2f, Sigma=%.2f", j + 1, amplitude, centroid, sigma));
text->DrawText(0.15, 0.8 - j * 0.05,
Form("Peak %d: Amp=%.2f±%.2f, Mean=%.2f±%.2f, Sigma=%.2f±%.2f, Chi2/NDF=%.2f",
j + 1, amplitude, amplitudeError, centroid, centroidError, sigma, sigmaError, chi2 / ndf));
// Save results
// Clean up
delete gaussFit;
}
// Update canvas for visualization
c1->Update();
std::cout << "Press Enter to view the next histogram..." << std::endl;
c1->WaitPrimitive(); // Wait until Enter is pressed in the ROOT console
}
// Close resources
inputFile->Close();
outFile.close();
delete c1;
}

309
GainMatchQQQ.C Normal file
View File

@ -0,0 +1,309 @@
#define GainMatchQQQ_cxx
#include "GainMatchQQQ.h"
#include <TH2.h>
#include <TF1.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TMath.h>
#include <TCutG.h>
#include <fstream>
#include <utility>
#include <algorithm>
#include <cmath>
#include <numeric>
#include "Armory/HistPlotter.h"
#include "TVector3.h"
#include "TGraphErrors.h"
#include "TF1.h"
#include <cmath>
TH2F *hQQQFVB;
HistPlotter *plotter;
int padID = 0;
TCutG *cut;
std::map<std::tuple<int, int, int>, std::vector<std::pair<double, double>>> dataPoints;
void GainMatchQQQ::Begin(TTree * /*tree*/)
{
plotter = new HistPlotter("GainQQQ.root", "TFILE");
TString option = GetOption();
hQQQFVB = new TH2F("hQQQFVB", "QQQ Front vs Back; Front E; Back E", 800, 0, 16000, 800, 0, 16000);
// Load the TCutG object
TFile *cutFile = TFile::Open("qqqcorr.root");
if (!cutFile || cutFile->IsZombie())
{
std::cerr << "Error: Could not open qqqcorr.root" << std::endl;
return;
}
cut = dynamic_cast<TCutG *>(cutFile->Get("qqqcorr"));
if (!cut)
{
std::cerr << "Error: Could not find TCutG named 'qqqcorr' in qqqcorr.root" << std::endl;
return;
}
cut->SetName("qqqcorr"); // Ensure the cut has the correct name
}
Bool_t GainMatchQQQ::Process(Long64_t entry)
{
int ringMults[16] = {0};
int wedgeMults[16] = {0};
std::vector<std::tuple<int, int, int, double, double>> events;
b_qqqMulti->GetEntry(entry);
b_qqqID->GetEntry(entry);
b_qqqCh->GetEntry(entry);
b_qqqE->GetEntry(entry);
b_qqqT->GetEntry(entry);
qqq.CalIndex();
for (int i = 0; i < qqq.multi; i++)
{
for (int j = i + 1; j < qqq.multi; j++)
{
if (qqq.id[i] == qqq.id[j])
{
int chWedge = -1;
int chRing = -1;
float eWedge = 0.0;
float eRing = 0.0;
if (qqq.ch[i] < 16 && qqq.ch[j] >= 16)
{
chWedge = qqq.ch[i];
eWedge = qqq.e[i];
chRing = qqq.ch[j] - 16;
eRing = qqq.e[j];
}
else if (qqq.ch[j] < 16 && qqq.ch[i] >= 16)
{
chWedge = qqq.ch[j];
eWedge = qqq.e[j];
chRing = qqq.ch[i] - 16;
eRing = qqq.e[i];
}
else
continue;
ringMults[chRing]++;
wedgeMults[chWedge]++;
hQQQFVB->Fill(eWedge, eRing);
events.emplace_back(qqq.id[i], chRing, chWedge, eRing, eWedge);
plotter->Fill2D(Form("hRaw_qqq%d_ring%d_wedge%d", qqq.id[i], chRing, chWedge), 800, 0, 3000, 800, 0, 3000, eWedge, eRing, "hRawQQQ");
// double ratio = (eWedge > 0.0) ? (eRing / eWedge) : 0.0;
// double maxslope = 1.5;
// bool validPoint = false;
// if (ratio < maxslope && ratio > 1. / maxslope)
// {
// // Accumulate data for gain matching
// dataPoints[{qqq.id[i], chRing, chWedge}].emplace_back(eWedge, eRing);
// plotter->Fill2D("hAll_in", 4000, 0, 16000, 4000, 0, 16000, eWedge, eRing);
// validPoint = true;
// }
// if (!validPoint)
// {
// plotter->Fill2D("hAll_out", 4000, 0, 16000, 4000, 0, 16000, eWedge, eRing);
// }
}
}
}
for (auto tuple : events)
{
auto [id, chr, chw, er, ew] = tuple;
if (ringMults[chr] > 1 || wedgeMults[chw] > 1)
continue; // ignore multiplicity > 1 events
double ratio = (ew > 0.0) ? (er / ew) : 0.0;
double maxslope = 1.5;
bool validPoint = false;
if (ratio < maxslope && ratio > 1. / maxslope)
{
// Accumulate data for gain matching
dataPoints[{id, chr, chw}].emplace_back(ew, er);
plotter->Fill2D("hAll_in", 4000, 0, 16000, 4000, 0, 16000, ew, er);
validPoint = true;
}
if (!validPoint)
{
plotter->Fill2D("hAll_out", 4000, 0, 16000, 4000, 0, 16000, ew, er);
}
}
return kTRUE;
}
void GainMatchQQQ::Terminate()
{
const int MAX_DET = 4;
const int MAX_RING = 16;
const int MAX_WEDGE = 16;
// We store gains locally just for the "corrected" plot,
// but the file will output Slopes for the global minimizer.
double gainW[MAX_DET][MAX_RING][MAX_WEDGE] = {{{0}}};
double gainR[MAX_DET][MAX_RING][MAX_WEDGE] = {{{0}}};
bool gainValid[MAX_DET][MAX_RING][MAX_WEDGE] = {{{false}}};
// Output file for the Minimizer
std::ofstream outFile("qqq_GainMatch.dat");
// Benchmark/Debug file
std::ofstream benchFile("benchmark_diff.dat");
benchFile << "ID Wedge Ring Chi2NDF Slope SlopeErr" << std::endl;
if (!outFile.is_open()) { std::cerr << "Error opening output file!" << std::endl; return; }
const int MIN_POINTS = 50;
const int MAX_ITER = 3; // Outlier rejection passes
const double CLIP_SIGMA = 2.5; // Sigma threshold for outliers
for (const auto &kv : dataPoints)
{
auto key = kv.first;
auto [id, ring, wedge] = key;
const auto &pts = kv.second;
if (pts.size() < (size_t)MIN_POINTS) continue;
std::vector<std::pair<double, double>> current_pts = pts;
double finalSlope = 0.0;
double finalSlopeErr = 0.0;
bool converged = false;
// --- Iterative Fitting ---
for (int iter = 0; iter < MAX_ITER; ++iter)
{
if (current_pts.size() < (size_t)MIN_POINTS) break;
std::vector<double> x, y, ex, ey;
for (const auto &p : current_pts)
{
x.push_back(p.first); // Wedge E
y.push_back(p.second); // Ring E
ex.push_back(std::sqrt(std::abs(p.first))); // Error in X (Poisson)
ey.push_back(std::sqrt(std::abs(p.second))); // Error in Y (Poisson)
// Sanity check to avoid 0 error
if(ex.back() < 1.0) ex.back() = 1.0;
if(ey.back() < 1.0) ey.back() = 1.0;
}
// 2. Create Graph
TGraphErrors *gr = new TGraphErrors(current_pts.size(), x.data(), y.data(), ex.data(), ey.data());
// 3. Fit Linear Function through Origin
TF1 *f1= new TF1("calibFit", "[0]*x", 0, 16000);
f1->SetParameter(0, 1.0);
// "Q"=Quiet, "N"=NoDraw, "S"=ResultPtr
// We do NOT use "W" (Ignore weights), we want to use the errors we set.
int fitStatus = gr->Fit(f1, "QNS");
if (fitStatus != 0) {
delete gr; delete f1;
break;
}
finalSlope = f1->GetParameter(0);
double chi2 = f1->GetChisquare();
double ndf = f1->GetNDF();
// Get the statistical error on the slope
double rawErr = f1->GetParError(0);
// SCALING ERROR:
// If Chi2/NDF > 1, the data scatters more than Poisson stats predict.
// // We inflate the error by sqrt(Chi2/NDF) to be conservative for the Minimizer.
// double redChi2 = (ndf > 0) ? (chi2 / ndf) : 1.0;
// double inflation = (redChi2 > 1.0) ? std::sqrt(redChi2) : 1.0;
// finalSlopeErr = rawErr * inflation;
// 4. Outlier Rejection
if (iter == MAX_ITER - 1) {
converged = true;
delete gr; delete f1;
break;
}
// Calculate Residuals
std::vector<double> residuals;
double sumSqResid = 0.0;
for(size_t k=0; k<current_pts.size(); ++k) {
double val = f1->Eval(current_pts[k].first);
double res = current_pts[k].second - val;
residuals.push_back(res);
sumSqResid += res*res;
}
// double sigma = std::sqrt(sumSqResid / current_pts.size());
// // Filter
// std::vector<std::pair<double, double>> next_pts;
// for(size_t k=0; k<current_pts.size(); ++k) {
// if(std::abs(residuals[k]) < CLIP_SIGMA * sigma) {
// next_pts.push_back(current_pts[k]);
// }
// }
// if (next_pts.size() == current_pts.size()) {
// converged = true;
// delete gr; delete f1;
// break;
// }
// current_pts = next_pts;
// delete gr; delete f1;
}
if (!converged || finalSlope <= 0) continue;
// --- Store/Output ---
// 1. Save locally for the verification plot (hAll)
// Approximate local gain for plotting purposes only
double gW_local = std::sqrt(finalSlope);
double gR_local = 1.0 / gW_local;
gainW[id][ring][wedge] = gW_local;
gainR[id][ring][wedge] = gR_local;
gainValid[id][ring][wedge] = true;
// 2. Write to File for Minimizer
// Format: ID Wedge Ring Slope Error
outFile << id << " " << wedge << " " << ring << " " << finalSlope << " " << finalSlopeErr << std::endl;
// 3. Benchmark Info
benchFile << id << " " << wedge << " " << ring << " "
<< finalSlope << " " << finalSlopeErr << std::endl;
}
outFile.close();
benchFile.close();
std::cout << "Gain matching with Errors complete." << std::endl;
// Plotting the corrected data (Visual check using local approx gains)
for (auto &kv : dataPoints)
{
int id, ring, wedge;
std::tie(id, ring, wedge) = kv.first;
if (!gainValid[id][ring][wedge]) continue;
auto &pts = kv.second;
for (auto &pr : pts)
{
double corrWedge = pr.first * gainW[id][ring][wedge];
double corrRing = pr.second * gainR[id][ring][wedge];
plotter->Fill2D("hAll", 4000, 0, 16000, 4000, 0, 16000, corrWedge, corrRing);
}
}
plotter->FlushToDisk();
}

114
GainMatchQQQ.h Normal file
View File

@ -0,0 +1,114 @@
#ifndef GainMatchQQQ_h
#define GainMatchQQQ_h
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TSelector.h>
#include "Armory/ClassDet.h"
class GainMatchQQQ : public TSelector {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
// Fixed size dimensions of array or collections stored in the TTree if any.
// Declaration of leaf types
Det sx3;
Det qqq;
Det pc ;
ULong64_t evID;
UInt_t run;
// List of branches
TBranch *b_eventID; //!
TBranch *b_run; //!
TBranch *b_sx3Multi; //!
TBranch *b_sx3ID; //!
TBranch *b_sx3Ch; //!
TBranch *b_sx3E; //!
TBranch *b_sx3T; //!
TBranch *b_qqqMulti; //!
TBranch *b_qqqID; //!
TBranch *b_qqqCh; //!
TBranch *b_qqqE; //!
TBranch *b_qqqT; //!
TBranch *b_pcMulti; //!
TBranch *b_pcID; //!
TBranch *b_pcCh; //!
TBranch *b_pcE; //!
TBranch *b_pcT; //!
GainMatchQQQ(TTree * /*tree*/ =0) : fChain(0) { }
virtual ~GainMatchQQQ() { }
virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree);
virtual void Init(TTree *tree);
virtual Bool_t Notify();
virtual Bool_t Process(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
virtual void SetOption(const char *option) { fOption = option; }
virtual void SetObject(TObject *obj) { fObject = obj; }
virtual void SetInputList(TList *input) { fInput = input; }
virtual TList *GetOutputList() const { return fOutput; }
virtual void SlaveTerminate();
virtual void Terminate();
ClassDef(GainMatchQQQ,0);
};
#endif
#ifdef GainMatchQQQ_cxx
void GainMatchQQQ::Init(TTree *tree){
// Set branch addresses and branch pointers
if (!tree) return;
fChain = tree;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("evID", &evID, &b_eventID);
fChain->SetBranchAddress("run", &run, &b_run);
sx3.SetDetDimension(24,12);
qqq.SetDetDimension(4,32);
pc.SetDetDimension(2,24);
fChain->SetBranchAddress("sx3Multi", &sx3.multi, &b_sx3Multi);
fChain->SetBranchAddress("sx3ID", &sx3.id, &b_sx3ID);
fChain->SetBranchAddress("sx3Ch", &sx3.ch, &b_sx3Ch);
fChain->SetBranchAddress("sx3E", &sx3.e, &b_sx3E);
fChain->SetBranchAddress("sx3T", &sx3.t, &b_sx3T);
fChain->SetBranchAddress("qqqMulti", &qqq.multi, &b_qqqMulti);
fChain->SetBranchAddress("qqqID", &qqq.id, &b_qqqID);
fChain->SetBranchAddress("qqqCh", &qqq.ch, &b_qqqCh);
fChain->SetBranchAddress("qqqE", &qqq.e, &b_qqqE);
fChain->SetBranchAddress("qqqT", &qqq.t, &b_qqqT);
fChain->SetBranchAddress("pcMulti", &pc.multi, &b_pcMulti);
fChain->SetBranchAddress("pcID", &pc.id, &b_pcID);
fChain->SetBranchAddress("pcCh", &pc.ch, &b_pcCh);
fChain->SetBranchAddress("pcE", &pc.e, &b_pcE);
fChain->SetBranchAddress("pcT", &pc.t, &b_pcT);
}
Bool_t GainMatchQQQ::Notify(){
return kTRUE;
}
void GainMatchQQQ::SlaveBegin(TTree * /*tree*/){
TString option = GetOption();
}
void GainMatchQQQ::SlaveTerminate(){
}
#endif // #ifdef GainMatchQQQ_cxx

4003
MakeVertex.C Executable file

File diff suppressed because it is too large Load Diff

133
MakeVertex.h Normal file
View File

@ -0,0 +1,133 @@
#ifndef MakeVertex_h
#define MakeVertex_h
#include <TROOT.h>
#include <TChain.h>
#include <TApplication.h>
#include <TFile.h>
#include <TSelector.h>
#include <iomanip>
#include <vector> // Required for vectors
#include <utility> // Required for std::pair
#include "Armory/ClassDet.h"
#include "Armory/ClassPW.h" // YOU ADDED THIS (Correct! Defines Coord)
class MakeVertex : public TSelector {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
// Declaration of leaf types
Det sx3;
Det qqq;
Det pc ;
Det misc;
ULong64_t evID;
UInt_t run;
// List of branches
TBranch *b_eventID; //!
TBranch *b_run; //!
TBranch *b_sx3Multi; //!
TBranch *b_sx3ID; //!
TBranch *b_sx3Ch; //!
TBranch *b_sx3E; //!
TBranch *b_sx3T; //!
TBranch *b_qqqMulti; //!
TBranch *b_qqqID; //!
TBranch *b_qqqCh; //!
TBranch *b_qqqE; //!
TBranch *b_qqqT; //!
TBranch *b_pcMulti; //!
TBranch *b_pcID; //!
TBranch *b_pcCh; //!
TBranch *b_pcE; //!
TBranch *b_pcT; //!
TBranch *b_miscMulti; //!
TBranch *b_miscID; //!
TBranch *b_miscCh; //!
TBranch *b_miscE; //!
TBranch *b_miscT; //!
TBranch *b_miscTf; //!
// 1. Geometry Cache
Coord Crossover[24][24][2];
// 2. Persistent Vectors (REQUIRED for the optimized .cxx to work)
std::vector<std::pair<int, double>> anodeHits;
std::vector<std::pair<int, double>> cathodeHits;
std::vector<std::pair<int, double>> corrcatMax;
std::vector<std::pair<int, double>> corranoMax;
std::vector<double> cathodeTimes;
std::vector<double> anodeTimes;
MakeVertex(TTree * /*tree*/ =0) : fChain(0) { }
virtual ~MakeVertex() { }
virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree);
virtual void Init(TTree *tree);
virtual Bool_t Notify();
virtual Bool_t Process(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
virtual void SetOption(const char *option) { fOption = option; }
virtual void SetObject(TObject *obj) { fObject = obj; }
virtual void SetInputList(TList *input) { fInput = input; }
virtual TList *GetOutputList() const { return fOutput; }
virtual void SlaveTerminate();
virtual void Terminate();
ClassDef(MakeVertex,0);
};
#endif
#ifdef MakeVertex_cxx
void MakeVertex::Init(TTree *tree){
if (!tree) return;
fChain = tree;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("evID", &evID, &b_eventID);
fChain->SetBranchAddress("run", &run, &b_run);
sx3.SetDetDimension(24,12);
qqq.SetDetDimension(4,32);
pc.SetDetDimension(2,24);
fChain->SetBranchAddress("sx3Multi", &sx3.multi, &b_sx3Multi);
fChain->SetBranchAddress("sx3ID", &sx3.id, &b_sx3ID);
fChain->SetBranchAddress("sx3Ch", &sx3.ch, &b_sx3Ch);
fChain->SetBranchAddress("sx3E", &sx3.e, &b_sx3E);
fChain->SetBranchAddress("sx3T", &sx3.t, &b_sx3T);
fChain->SetBranchAddress("qqqMulti", &qqq.multi, &b_qqqMulti);
fChain->SetBranchAddress("qqqID", &qqq.id, &b_qqqID);
fChain->SetBranchAddress("qqqCh", &qqq.ch, &b_qqqCh);
fChain->SetBranchAddress("qqqE", &qqq.e, &b_qqqE);
fChain->SetBranchAddress("qqqT", &qqq.t, &b_qqqT);
fChain->SetBranchAddress("pcMulti", &pc.multi, &b_pcMulti);
fChain->SetBranchAddress("pcID", &pc.id, &b_pcID);
fChain->SetBranchAddress("pcCh", &pc.ch, &b_pcCh);
fChain->SetBranchAddress("pcE", &pc.e, &b_pcE);
fChain->SetBranchAddress("pcT", &pc.t, &b_pcT);
fChain->SetBranchAddress("miscMulti", &misc.multi, &b_miscMulti);
fChain->SetBranchAddress("miscID", &misc.id, &b_miscID);
fChain->SetBranchAddress("miscCh", &misc.ch, &b_miscCh);
fChain->SetBranchAddress("miscE", &misc.e, &b_miscE);
fChain->SetBranchAddress("miscT", &misc.t, &b_miscT);
fChain->SetBranchAddress("miscf", &misc.tf, &b_miscTf);
}
Bool_t MakeVertex::Notify(){
return kTRUE;
}
void MakeVertex::SlaveBegin(TTree * /*tree*/){
// TString option = GetOption();
}
void MakeVertex::SlaveTerminate(){
}
#endif // #ifdef MakeVertex_cxx

139
MatchAndPlotCentroids.C Normal file
View File

@ -0,0 +1,139 @@
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <iostream>
#include <TGraph.h>
#include <TF1.h>
#include <TCanvas.h>
#include <TH1.h>
void MatchAndPlotCentroids() {
// Open the centroid data file
std::ifstream inputFile("centroids_27Al.txt");
// std::ifstream inputFile("centroids_17F.txt");
if (!inputFile.is_open()) {
std::cerr << "Error: Could not open Centroids.txt" << std::endl;
return;
}
// Data structure to store centroids by histogram and peak number
std::map<int, std::map<int, double>> centroidData;
// Read data from the file
std::string line;
while (std::getline(inputFile, line)) {
std::istringstream iss(line);
int histogramIndex, peakNumber;
double centroid;
if (iss >> histogramIndex >> peakNumber >> centroid) {
centroidData[histogramIndex][peakNumber] = centroid;
}
}
inputFile.close();
// Ensure histogram 24 exists and has data
if (centroidData.find(1) == centroidData.end()) {
std::cerr << "Error: Histogram 0 not found in the data!" << std::endl;
return;
}
// Reference centroids from histogram 24
const auto& referenceCentroids = centroidData[1];
std::ofstream outputFile("slope_intercept_results.dat");
if (!outputFile.is_open()) {
std::cerr << "Error: Could not open the output file for writing!" << std::endl;
return;
}
outputFile << "Histogram Number\tSlope\tIntercept\n";
// Loop through histograms 25 to 47
// 1. Create a SINGLE canvas BEFORE the loop
TCanvas *c1 = new TCanvas("c1", "Centroid Fit Viewer", 800, 600);
for (int targetHist = 0; targetHist <= 23; targetHist++) {
// Ensure the target histogram exists and matches in peak numbers
if (centroidData.find(targetHist) == centroidData.end() || centroidData[targetHist].size() != referenceCentroids.size()) {
//4th cnetroid data point for 19 was generated using the 3 datqa points for the slope of wires 0 and 19
std::cout << "Skipping Histogram " << targetHist << " due to mismatched or missing data." << std::endl;
continue;
}
// Prepare x and y values for TGraph
std::vector<double> xValues, yValues;
for (const auto& [peakNumber, refCentroid] : referenceCentroids) {
if (centroidData[targetHist].find(peakNumber) != centroidData[targetHist].end()) {
yValues.push_back(refCentroid);
xValues.push_back(centroidData[targetHist][peakNumber]);
} else {
std::cerr << "Warning: Peak " << peakNumber << " missing in histogram " << targetHist << std::endl;
}
}
if (xValues.size() < 3) {
std::cout << "Skipping Histogram " << targetHist << " as it has less than 3 matching centroids." << std::endl;
continue;
}
// Create a TGraph
TGraph *graph = new TGraph(xValues.size(), &xValues[0], &yValues[0]);
graph->SetTitle(Form("Centroid of Histogram %d vs 1", targetHist));
graph->GetYaxis()->SetTitle("Centroid of Histogram 1");
graph->GetXaxis()->SetTitle(Form("Centroid of Histogram %d", targetHist));
graph->SetMarkerStyle(20);
graph->SetMarkerSize(1.0);
graph->SetMarkerColor(kBlue);
graph->Draw("AP");
// Draw the graph
graph->Draw("AP");
double minX = *std::min_element(xValues.begin(), xValues.end());
double maxX = *std::max_element(xValues.begin(), xValues.end());
// Fit the data with a linear function
TF1 *fitLine = new TF1("fitLine", "pol1", minX, maxX); // Adjust range as needed
fitLine->SetLineColor(kRed); // Set the line color to distinguish it
fitLine->SetLineWidth(2); // Thicker line for visibility
graph->Fit(fitLine, "M");
fitLine->Draw("same");
fitLine->SetParLimits(0, -10, 10); // Limit intercept between -10 and 10
fitLine->SetParLimits(1, 0, 2);
// Extract slope and intercept
double slope = fitLine->GetParameter(1);
double intercept = fitLine->GetParameter(0);
outputFile << targetHist << "\t" << slope << "\t" << intercept << "\n";
std::cout << "Histogram 24 vs " << targetHist << ": Slope = " << slope << ", Intercept = " << intercept << std::endl;
std::vector<double> residuals;
for (size_t i = 0; i < xValues.size(); ++i) {
double fittedY = fitLine->Eval(xValues[i]); // Evaluate fitted function at x
double residual = yValues[i] - fittedY; // Residual = observed - fitted
residuals.push_back(residual);
}
// Create a graph for the residuals
/*TGraph *residualGraph = new TGraph(residuals.size(), &xValues[0], &residuals[0]);
residualGraph->SetTitle(Form("Residuals for Histogram 24 vs %d", targetHist));
residualGraph->GetYaxis()->SetTitle("Residuals");
residualGraph->GetXaxis()->SetTitle(Form("Centroid of Histogram %d", targetHist));
residualGraph->SetMarkerStyle(20);
residualGraph->SetMarkerSize(1.0);
residualGraph->SetMarkerColor(kGreen);
// Draw the residuals plot below the original plot (can be on a new canvas if preferred)
TCanvas *c2 = new TCanvas(Form("c_residuals_24_vs_%d", targetHist), Form("Residuals for Centroid 24 vs %d", targetHist), 800, 400);
residualGraph->Draw("AP");*/
c1->Update();
//c2->Update();
std::cout << "Press Enter to continue..." << std::endl;
//std::cin.get();
c1->WaitPrimitive();
//c2->WaitPrimitive();
//std::cin.get();
//std::cin.get();
}
outputFile.close();
std::cout << "Results written to slope_intercept_results.txt" << std::endl;
}

359
MiscEdE.C Normal file
View File

@ -0,0 +1,359 @@
#include "TFile.h"
#include "TTree.h"
#include "TChain.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TCutG.h"
#include "TKey.h"
#include "TString.h"
#include "TSystem.h"
#include <map>
#include <vector>
#include <utility>
#include <cstdlib>
namespace
{
constexpr double kAdcMax = 16384; // 14-bit-ish ADC range for axes
struct HitData
{
double e;
unsigned long long t;
};
}
void MiscEdE(const char *f0,
const char *f1 = "", const char *f2 = "", const char *f3 = "",
const char *f4 = "", const char *f5 = "", const char *f6 = "",
const char *f7 = "", const char *f8 = "", const char *f9 = "")
{
std::vector<TString> inputs;
for (const char *f : {f0, f1, f2, f3, f4, f5, f6, f7, f8, f9})
if (f && f[0])
inputs.emplace_back(f);
if (inputs.empty())
{
printf("MiscEdE: no input files given.\n");
return;
}
TChain *tree = new TChain("tree");
for (auto &in : inputs)
{
if (gSystem->AccessPathName(in))
{
printf("MiscEdE: WARNING input not found, skipping: %s\n", in.Data());
continue;
}
tree->Add(in);
}
if (tree->GetNtrees() == 0)
{
printf("MiscEdE: no readable inputs.\n");
return;
}
// ---------------------------------------------------------
// Bash Environment Variable Extraction
// ---------------------------------------------------------
int runNumber = -1;
if (gSystem->Getenv("CURRENT_RUN")) {
runNumber = std::atoi(gSystem->Getenv("CURRENT_RUN"));
}
printf("MiscEdE: Run Number loaded from Bash: %d\n", runNumber);
TString cutDir = "~/ANASEN_analysis"; // Fallback if not run via bash
if (gSystem->Getenv("CUT_DIR")) {
cutDir = gSystem->Getenv("CUT_DIR");
}
// ---------------------------------------------------------
// Run-Dependent Channel Routing
// ---------------------------------------------------------
// Defaults (Run <= 180)
int snLolli = 405, chLolli = 9;
int snSi = 405, chSi = 11;
int snRF = 405, chRF = 15;
int snMCP = 405, chMCP = 14;
if (runNumber > 180 && runNumber <= 282) {
chRF = 10;
}
else if (runNumber > 282 && runNumber <= 322) {
snRF = 89; chRF = 0;
snMCP = 89; chMCP = 1;
}
else if (runNumber > 322) {
snRF = 89; chRF = 0;
snMCP = 89; chMCP = 2;
}
// Composite Unique IDs (UID = Board * 100 + Channel) to prevent collisions
int uidLollipop = snLolli * 100 + chLolli;
int uidSiMon = snSi * 100 + chSi;
int uidRF = snRF * 100 + chRF;
int uidMCP = snMCP * 100 + chMCP;
printf(" -> Routed Lollipop : Board %d, Ch %d (UID: %d)\n", snLolli, chLolli, uidLollipop);
printf(" -> Routed Si Monitor: Board %d, Ch %d (UID: %d)\n", snSi, chSi, uidSiMon);
printf(" -> Routed RF : Board %d, Ch %d (UID: %d)\n", snRF, chRF, uidRF);
printf(" -> Routed MCP : Board %d, Ch %d (UID: %d)\n", snMCP, chMCP, uidMCP);
// ---------------------------------------------------------
// Exact schema matching EventBuilder.cpp
// ---------------------------------------------------------
const int MAX_MULTI = 2000;
unsigned int multi = 0;
unsigned short sn[MAX_MULTI];
unsigned short ch[MAX_MULTI];
unsigned short e[MAX_MULTI];
unsigned long long e_t[MAX_MULTI]; // Timestamp branch is "e_t"
tree->SetBranchAddress("multi", &multi);
tree->SetBranchAddress("sn", sn);
tree->SetBranchAddress("ch", ch);
tree->SetBranchAddress("e", e);
tree->SetBranchAddress("e_t", e_t);
TString stem = gSystem->BaseName(inputs[0].Data());
if (stem.EndsWith(".root"))
stem.Remove(stem.Length() - 5);
TString outName = "MiscEdE_" + stem + ".root";
TFile *out = new TFile(outName, "recreate");
// ---------------------------------------------------------
// Load the 17F and 16O TCutGs from file
// ---------------------------------------------------------
TCutG *cut17F = nullptr;
TString path17F = gSystem->ExpandPathName(Form("%s/17FCut.root", cutDir.Data()));
if (!gSystem->AccessPathName(path17F))
{
TFile *fCut = TFile::Open(path17F);
if (fCut && !fCut->IsZombie())
{
for (auto keyObj : *fCut->GetListOfKeys())
{
TKey *key = (TKey *)keyObj;
if (TString(key->GetClassName()) == "TCutG")
{
cut17F = (TCutG *)key->ReadObj()->Clone("cut17F");
break;
}
}
fCut->Close();
}
}
TCutG *cut16O = nullptr;
TString path16O = gSystem->ExpandPathName(Form("%s/16OCut.root", cutDir.Data()));
if (!gSystem->AccessPathName(path16O))
{
TFile *fCut = TFile::Open(path16O);
if (fCut && !fCut->IsZombie())
{
for (auto keyObj : *fCut->GetListOfKeys())
{
TKey *key = (TKey *)keyObj;
if (TString(key->GetClassName()) == "TCutG")
{
cut16O = (TCutG *)key->ReadObj()->Clone("cut16O");
break;
}
}
fCut->Close();
}
}
out->cd();
// ---------------------------------------------------------
// Prepare Histograms
// ---------------------------------------------------------
std::map<int, TH2D*> hEvsChMap;
auto getEvsCh = [&](int boardSN) -> TH2D* {
if (hEvsChMap.count(boardSN)) return hEvsChMap[boardSN];
TH2D *h = new TH2D(Form("h2_E_vs_ch_bd%d", boardSN), Form("Board %d: E vs channel;board channel;E [ADC]", boardSN), 16, -0.5, 15.5, 800, 0, kAdcMax);
hEvsChMap[boardSN] = h;
return h;
};
TH2D *h2_EvsdT_LolliSi = new TH2D("EvsdT_Lollipop_Si", "Energy Si vs dT (Lollipop - Si);dT [ticks];Si E [ADC]", 500, 0, 2000, 400, 0, kAdcMax);
TH2D *h2_TOF_SiRF = new TH2D("TOF_Si_RF", "Time of Flight: Energy Si vs (T_Si - T_RF);T_Si - T_RF [ticks];Si E [ADC]", 500, 0, 2000, 400, 0, kAdcMax);
// Dynamic Pairwise E-dE mapped by UID
std::map<std::pair<int, int>, TH2D *> hEdE;
auto getEdE = [&](int uidA, int uidB) -> TH2D * {
if (uidA > uidB) std::swap(uidA, uidB);
auto key = std::make_pair(uidA, uidB);
auto it = hEdE.find(key);
if (it != hEdE.end()) return it->second;
TString name = Form("h2_ede_bd%d_ch%d_vs_bd%d_ch%d", uidA/100, uidA%100, uidB/100, uidB%100);
TString title = Form("E-dE: Bd %d Ch %d (x) vs Bd %d Ch %d (y);X E [ADC];Y E [ADC]", uidA/100, uidA%100, uidB/100, uidB%100);
TH2D *h = new TH2D(name, title, 400, 0, kAdcMax, 400, 0, kAdcMax);
hEdE[key] = h;
return h;
};
// 17F Gated Plots
TH2D *hEdE_17F = nullptr;
TH2D *hEdE_inv = nullptr;
TH2D *h2_EvsdT_LolliSi_17F = nullptr;
TH2D *h2_TOF_SiRF_17F = nullptr;
TH1D *h1_dT_17F = nullptr;
if (cut17F)
{
hEdE_17F = new TH2D("EdE_lollipopIC_vs_SiMonitor_17FCut", "lollipop IC vs Si monitor (17F Gated);Si monitor E [ADC];lollipop IC E [ADC]", 400, 0, kAdcMax, 400, 0, kAdcMax);
hEdE_inv = new TH2D("EdE_lollipopIC_vs_SiMonitor_17FCut_Inverse", "lollipop IC vs Si monitor (Inverse 17F Gated);Si monitor E [ADC];lollipop IC E [ADC]", 400, 0, kAdcMax, 400, 0, kAdcMax);
h2_EvsdT_LolliSi_17F = new TH2D("EvsdT_Lollipop_Si_17FCut", "Energy Si vs dT (17F Gated);dT (Lollipop - Si) [ticks];Si E [ADC]", 500, 0, 2000, 400, 0, kAdcMax);
h2_TOF_SiRF_17F = new TH2D("TOF_Si_RF_17FCut", "Si TOF vs Energy (17F Gated);T_Si - T_RF [ticks];Si E [ADC]", 500, 0, 2000, 400, 0, kAdcMax);
h1_dT_17F = new TH1D("dT_Lollipop_Si_17FCut", "dT Lollipop-Si (17F Gated);T_Lollipop - T_Si [ticks]", 500, 0, 2000);
}
// 16O Gated Plots
TH2D *hEdE_16O = nullptr;
TH2D *h2_EvsdT_LolliSi_16O = nullptr;
TH2D *h2_TOF_SiRF_16O = nullptr;
TH1D *h1_dT_16O = nullptr;
if (cut16O)
{
hEdE_16O = new TH2D("EdE_lollipopIC_vs_SiMonitor_16OCut", "lollipop IC vs Si monitor (16O Gated);Si monitor E [ADC];lollipop IC E [ADC]", 400, 0, kAdcMax, 400, 0, kAdcMax);
h2_EvsdT_LolliSi_16O = new TH2D("EvsdT_Lollipop_Si_16OCut", "Energy Si vs dT (16O Gated);dT (Lollipop - Si) [ticks];Si E [ADC]", 500, 0, 2000, 400, 0, kAdcMax);
h2_TOF_SiRF_16O = new TH2D("TOF_Si_RF_16OCut", "Si TOF vs Energy (16O Gated);T_Si - T_RF [ticks];Si E [ADC]", 500, 0, 2000, 800, 0, kAdcMax);
h1_dT_16O = new TH1D("dT_Lollipop_Si_16OCut", "dT Lollipop-Si (16O Gated);T_Lollipop - T_Si [ticks]", 500, 0, 2000);
}
Long64_t nEnt = tree->GetEntries();
printf("MiscEdE: %lld entries across %d file(s) -> %s\n", nEnt, tree->GetNtrees(), outName.Data());
Long64_t used = 0;
for (Long64_t i = 0; i < nEnt; ++i)
{
tree->GetEntry(i);
// We map hits by UID instead of standard channel to prevent overlaps between Bd405 and Bd89
std::map<int, HitData> hit;
for (unsigned int j = 0; j < multi && j < (unsigned)MAX_MULTI; ++j)
{
// Only care about MISC boards 405 and 89
if (sn[j] != 405 && sn[j] != 89)
continue;
int c = ch[j];
int uid = (sn[j] * 100) + ch[j];
double en = e[j];
unsigned long long ts = e_t[j];
auto it = hit.find(uid);
if (it == hit.end() || en > it->second.e)
hit[uid] = {en, ts};
getEvsCh(sn[j])->Fill(c, en);
}
if (hit.empty())
continue;
++used;
// ---------------------------------------------------------
// Generic Dynamic Pairwise E-dE Logic across all UIDs
// ---------------------------------------------------------
for (auto a = hit.begin(); a != hit.end(); ++a)
{
for (auto b = std::next(a); b != hit.end(); ++b)
{
if (a->second.e > 500 && b->second.e > 500)
{
getEdE(a->first, b->first)->Fill(a->second.e, b->second.e);
}
}
}
// ---------------------------------------------------------
// Core Timing and PID Gating Logic (Lollipop-Si specific)
// ---------------------------------------------------------
if (hit.count(uidLollipop) && hit.count(uidSiMon))
{
double e_lol = hit[uidLollipop].e;
double e_si = hit[uidSiMon].e;
// Calculate delta T safely across potential CAEN rollovers
double dt_lol_si = static_cast<double>(hit[uidLollipop].t) - static_cast<double>(hit[uidSiMon].t);
if (e_lol > 500 && e_si > 500)
{
h2_EvsdT_LolliSi->Fill(dt_lol_si, e_si);
bool is17F = cut17F && cut17F->IsInside(e_si, e_lol);
bool is16O = cut16O && cut16O->IsInside(e_si, e_lol);
if (is17F)
{
hEdE_17F->Fill(e_si, e_lol);
h2_EvsdT_LolliSi_17F->Fill(dt_lol_si, e_si);
h1_dT_17F->Fill(dt_lol_si);
}
else if (cut17F)
{
hEdE_inv->Fill(e_si, e_lol);
}
if (is16O)
{
hEdE_16O->Fill(e_si, e_lol);
h2_EvsdT_LolliSi_16O->Fill(dt_lol_si, e_si);
h1_dT_16O->Fill(dt_lol_si);
}
// Generate absolute TOF if the RF channel fired
if (hit.count(uidRF))
{
double tof = static_cast<double>(hit[uidSiMon].t) - static_cast<double>(hit[uidRF].t);
h2_TOF_SiRF->Fill(tof, e_si);
if (is17F)
h2_TOF_SiRF_17F->Fill(tof, e_si);
if (is16O)
h2_TOF_SiRF_16O->Fill(tof, e_si);
}
}
}
}
// ---------------------------------------------------------
// Purge Sparse E-dE Histograms (< 500 counts)
// ---------------------------------------------------------
for (auto it = hEdE.begin(); it != hEdE.end();)
{
if (it->second->GetEntries() < 500)
{
delete it->second; // Free memory and remove from ROOT file
it = hEdE.erase(it);
}
else
{
++it;
}
}
// Convenience alias: Transpose generic plot to correctly place stopping E on X
if (hEdE.count({uidLollipop, uidSiMon}))
{
TH2D *src = hEdE[{uidLollipop, uidSiMon}];
TH2D *alias = new TH2D("EdE_lollipopIC_vs_SiMonitor_Ungated",
Form("lollipop IC vs Si monitor (Ungated);Bd %d Ch %d (Si) E [ADC];Bd %d Ch %d (Lolli) E [ADC]", snSi, chSi, snLolli, chLolli),
src->GetNbinsY(), src->GetYaxis()->GetXmin(), src->GetYaxis()->GetXmax(),
src->GetNbinsX(), src->GetXaxis()->GetXmin(), src->GetXaxis()->GetXmax());
for (int ix = 1; ix <= src->GetNbinsX(); ++ix)
for (int iy = 1; iy <= src->GetNbinsY(); ++iy)
alias->SetBinContent(iy, ix, src->GetBinContent(ix, iy)); // (x,y) -> (y,x)
}
out->Write();
out->Close();
printf("MiscEdE: Processed %lld valid MISC events. Wrote %s\n", used, outName.Data());
}

View File

@ -1,14 +1,13 @@
#define Analyzer_cxx #define PCGainMatch_cxx
#include "Analyzer.h" #include "PCGainMatch.h"
#include <TH2.h> #include <TH2.h>
#include <TStyle.h> #include <TStyle.h>
#include <TCanvas.h> #include <TCanvas.h>
#include <TMath.h> #include <TMath.h>
#include <TCutG.h>
#include <utility> #include <utility>
#include <algorithm> #include <algorithm>
#include "Armory/ClassSX3.h" #include "Armory/ClassSX3.h"
#include "Armory/ClassPW.h" #include "Armory/ClassPW.h"
@ -28,6 +27,13 @@ TH2F * hqqqVpcIndex;
TH2F * hqqqVpcE; TH2F * hqqqVpcE;
TH2F * hsx3VpcE; TH2F * hsx3VpcE;
TH2F * hanVScatsum; TH2F * hanVScatsum;
TH2F * hanVScatsum_a[24];
TH2F * hanVScatsum_hcut;
TH2F * hanVScatsum_lcut;
TH2F * hAnodeHits;
TH1F * hAnodeMultiplicity;
int padID = 0; int padID = 0;
SX3 sx3_contr; SX3 sx3_contr;
@ -36,13 +42,20 @@ TVector3 hitPos;
bool HitNonZero; bool HitNonZero;
TH1F * hZProj; TH1F * hZProj;
TCutG *AnCatSum_high;
TCutG *AnCatSum_low;
TCutG *PCCoinc_cut1;
TCutG *PCCoinc_cut2;
bool inCuth;
bool inCutl;
bool inPCCut;
void Analyzer::Begin(TTree * /*tree*/){ void PCGainMatch::Begin(TTree * /*tree*/){
TString option = GetOption(); TString option = GetOption();
hsx3IndexVE = new TH2F("hsx3IndexVE", "SX3 index vs Energy; sx3 index ; Energy", 24*12, 0, 24*12, 400, 0, 5000); hsx3IndexVE->SetNdivisions( -612, "x"); hsx3IndexVE = new TH2F("hsx3IndexVE", "SX3 index vs Energy; sx3 index ; Energy", 24*12, 0, 24*12, 400, 0, 5000); hsx3IndexVE->SetNdivisions( -612, "x");
hqqqIndexVE = new TH2F("hqqqIndexVE", "QQQ index vs Energy; QQQ index ; Energy", 4*2*16, 0, 4*2*16, 400, 0, 5000); hqqqIndexVE->SetNdivisions( -1204, "x"); hqqqIndexVE = new TH2F("hqqqIndexVE", "QQQ index vs Energy; QQQ index ; Energy", 4*2*16, 0, 4*2*16, 400, 0, 5000); hqqqIndexVE->SetNdivisions( -1204, "x");
hpcIndexVE = new TH2F("hpcIndexVE", "PC index vs Energy; PC index ; Energy", 2*24, 0, 2*24, 400, 0, 4000); hpcIndexVE->SetNdivisions( -1204, "x"); hpcIndexVE = new TH2F("hpcIndexVE", "PC index vs Energy; PC index ; Energy", 2*24, 0, 2*24, 800, 0, 16000); hpcIndexVE->SetNdivisions( -1204, "x");
hsx3Coin = new TH2F("hsx3Coin", "SX3 Coincident", 24*12, 0, 24*12, 24*12, 0, 24*12); hsx3Coin = new TH2F("hsx3Coin", "SX3 Coincident", 24*12, 0, 24*12, 24*12, 0, 24*12);
@ -66,20 +79,37 @@ void Analyzer::Begin(TTree * /*tree*/){
hsx3VpcE->SetNdivisions( -612, "x"); hsx3VpcE->SetNdivisions( -612, "x");
hsx3VpcE->SetNdivisions( -12, "y"); hsx3VpcE->SetNdivisions( -12, "y");
hZProj = new TH1F("hZProj", "Z Projection", 200, -600, 600); hZProj = new TH1F("hZProj", "Nos of anodes", 20, 0, 19);
hAnodeHits = new TH2F("hAnodeHits", "Anode vs Anode Energy, Anode ID; Anode E", 24,0 , 23, 400, 0 , 20000);
hanVScatsum = new TH2F("hanVScatsum", "Anode vs Cathode Sum; Anode E; Cathode E", 400,0 , 10000, 400, 0 , 16000); hAnodeMultiplicity = new TH1F("hAnodeMultiplicity", "Number of Anodes/Event", 40, 0, 40);
hanVScatsum = new TH2F("hanVScatsum", "Anode vs Cathode Sum; Anode E; Cathode E", 400,0 , 10000, 800, 0 , 16000);
for (int i = 0; i < 24; i++) {
TString histName = Form("hAnodeVsCathode_%d", i);
TString histTitle = Form("Anode %d vs Cathode Sum; Anode E; Cathode Sum E", i);
hanVScatsum_a[i] = new TH2F(histName, histTitle, 400, 0, 10000, 400, 0, 16000);
}
hanVScatsum_lcut = new TH2F("hanVScatsum_LCUT", "Anode vs Cathode Sum; Anode E; Cathode E", 400,0 , 16000, 400, 0 , 16000);
hanVScatsum_hcut = new TH2F("hanVScatsum_HCUT", "Anode vs Cathode Sum; Anode E; Cathode E", 400,0 , 16000, 400, 0 , 16000);
sx3_contr.ConstructGeo(); sx3_contr.ConstructGeo();
pw_contr.ConstructGeo(); pw_contr.ConstructGeo();
// TFile *f1 = new TFile("AnCatSum_high.root");
// TFile *f2 = new TFile("AnCatSum_low.root");
// TFile *f3 = new TFile("PCCoinc_cut1.root");
// TFile *f4 = new TFile("PCCoinc_cut2.root");
// AnCatSum_high= (TCutG*)f1->Get("AnCatSum_high");
// AnCatSum_low= (TCutG*)f2->Get("AnCatSum_low");
// PCCoinc_cut1= (TCutG*)f3->Get("PCCoinc_cut1");
// PCCoinc_cut2= (TCutG*)f4->Get("PCCoinc_cut2");
} }
Bool_t Analyzer::Process(Long64_t entry){ Bool_t PCGainMatch::Process(Long64_t entry){
// if (entry % 1000000 == 0) {
// std::cout << "Processing entry: " << entry << std::endl;
// }
// if ( entry > 100 ) return kTRUE; // if ( entry > 100 ) return kTRUE;
hitPos.Clear(); hitPos.Clear();
@ -111,23 +141,139 @@ Bool_t Analyzer::Process(Long64_t entry){
// sx3.Print(); // sx3.Print();
//########################################################### Raw data //########################################################### Raw data
// //======================= PC
std::vector<std::pair<int, double>> anodeHits={};
std::vector<std::pair<int, double>> cathodeHits={};
int aID = 0;
int cID = 0;
float aE = 0;
float cE = 0;
// Define the excluded SX3 and QQQ channels
// std::unordered_set<int> excludeSX3 = {34, 35, 36, 37, 61, 62, 67, 73, 74, 75, 76, 77, 78, 79, 80, 93, 97, 100, 103, 108, 109, 110, 111, 112};
// std::unordered_set<int> excludeQQQ = {0, 17, 109, 110, 111, 112, 113, 119, 127, 128};
// inCuth=false;
// inCutl=false;
// inPCCut=false;
for( int i = 0; i < pc.multi; i ++){
if(pc.e[i]>50 && pc.multi<7){
float aESum = 0;
float cESum = 0;
if (pc.index[i] < 24 ) {
anodeHits.push_back(std::pair<int, double>(pc.index[i], pc.e[i]));
} else if (pc.index[i] >= 24) {
cathodeHits.push_back(std::pair<int, double>(pc.index[i], pc.e[i]));
}
for(int j=i+1;j<pc.multi;j++){
// if(PCCoinc_cut1->IsInside(pc.index[i], pc.index[j]) || PCCoinc_cut2->IsInside(pc.index[i], pc.index[j])){
// // hpcCoin->Fill(pc.index[i], pc.index[j]);
// inPCCut = true;
// }
hpcCoin->Fill(pc.index[i], pc.index[j]);
}
if (anodeHits.size()==1 && cathodeHits.size() >= 1) {
for (const auto& anode : anodeHits) {
// for(int l=0; l<sx3.multi; l++){
// if (sx3.index[l]==80){
aID = anode.first;
aE = anode.second;
aESum += aE;
// printf("aID : %d, aE : %f\n", aID, aE);
}
// printf("aID : %d, aE : %f, cE : %f\n", aID, aE, cE);
for (const auto& cathode : cathodeHits) {
cID = cathode.first;
cE = cathode.second;
// if(cE>cEMax){
// cEMax = cE;
// cIDMax = cID;
// }
// if(cE>cEnextMax && cE<cEMax){
// cEnextMax = cE;
// cIDnextMax = cID;
// }
cESum += cE;
}
// }
// inCuth = false;
// inCutl = false;
// inPCCut = false;
// for(int j=i+1;j<pc.multi;j++){
// if(PCCoinc_cut1->IsInside(pc.index[i], pc.index[j]) || PCCoinc_cut2->IsInside(pc.index[i], pc.index[j])){
// // hpcCoin->Fill(pc.index[i], pc.index[j]);
// inPCCut = true;
// }
// hpcCoin->Fill(pc.index[i], pc.index[j]);
// }
// Check if the accumulated energies are within the defined ranges
// if (AnCatSum_high && AnCatSum_high->IsInside(aESum, cESum)) {
// inCuth = true;
// }
// if (AnCatSum_low && AnCatSum_low->IsInside(aESum, cESum)) {
// inCutl = true;
// }
// Fill histograms based on the cut conditions
// if (inCuth && inPCCut) {
// hanVScatsum_hcut->Fill(aESum, cESum);
// }
// if (inCutl && inPCCut) {
// hanVScatsum_lcut->Fill(aESum, cESum);
// }
// for(auto anode : anodeHits){
// float aE = anode.second;
// aESum += aE;
// if(inPCCut){
hanVScatsum->Fill(aESum, cESum);
// }
if (aID < 24 && aE > 50) {
hanVScatsum_a[aID]->Fill(aE, cESum);
}
// }
// Fill histograms for the `pc` data
hpcIndexVE->Fill(pc.index[i], pc.e[i]);
// if(inPCCut){
hAnodeMultiplicity->Fill(anodeHits.size());
// }
}
}
}
// //======================= SX3 // //======================= SX3
std::vector<std::pair<int, int>> ID; // first = id, 2nd = index std::vector<std::pair<int, int>> ID; // first = id, 2nd = index
for( int i = 0; i < sx3.multi; i ++){ for( int i = 0; i < sx3.multi; i ++){
ID.push_back(std::pair<int, int>(sx3.id[i], i)); if(sx3.e[i]>50){
ID.push_back(std::pair<int, int>(sx3.id[i], i));
hsx3IndexVE->Fill( sx3.index[i], sx3.e[i] );
hsx3IndexVE->Fill( sx3.index[i], sx3.e[i] ); for( int j = i+1; j < sx3.multi; j++){
hsx3Coin->Fill( sx3.index[i], sx3.index[j]);
}
for( int j = i+1; j < sx3.multi; j++){ for( int j = 0; j < pc.multi; j++){
hsx3Coin->Fill( sx3.index[i], sx3.index[j]); hsx3VpcIndex->Fill( sx3.index[i], pc.index[j] );
} // if( sx3.ch[index] > 8 ){
// hsx3VpcE->Fill( sx3.e[i], pc.e[j] );
for( int j = 0; j < pc.multi; j++){ // }
hsx3VpcIndex->Fill( sx3.index[i], pc.index[j] ); }
// if( sx3.ch[index] > 8 ){
// hsx3VpcE->Fill( sx3.e[i], pc.e[j] );
// }
} }
} }
@ -179,8 +325,9 @@ Bool_t Analyzer::Process(Long64_t entry){
sx3ChBk = sx3.ch[index]; sx3ChBk = sx3.ch[index];
} }
for( int j = 0; j < pc.multi; j++){ for( int j = 0; j < pc.multi; j++){
// hsx3VpcIndex->Fill( sx3.index[i], pc.index[j] ); // hsx3VpcIndex->Fill( sx3.index[i], pc.index[j] );
if( sx3.ch[index] > 8 ){ if( sx3.ch[index] > 8 && pc.index[j]<24 && pc.e[j]>50 ){
hsx3VpcE->Fill( sx3.e[i], pc.e[j] ); hsx3VpcE->Fill( sx3.e[i], pc.e[j] );
// hpcIndexVE->Fill( pc.index[i], pc.e[i] ); // hpcIndexVE->Fill( pc.index[i], pc.e[i] );
} }
@ -198,125 +345,30 @@ Bool_t Analyzer::Process(Long64_t entry){
// //======================= QQQ // //======================= QQQ
for( int i = 0; i < qqq.multi; i ++){ for( int i = 0; i < qqq.multi; i ++){
// for( int j = 0; j < pc.multi; j++){
// if(pc.index[j]==4){ // for( int j = 0; j < pc.multi; j++){
if(qqq.e[i]>50 ){
hqqqIndexVE->Fill( qqq.index[i], qqq.e[i] ); hqqqIndexVE->Fill( qqq.index[i], qqq.e[i] );
// } for( int j = 0; j < qqq.multi; j++){
// } if ( j == i ) continue;
for( int j = 0; j < qqq.multi; j++){ hqqqCoin->Fill( qqq.index[i], qqq.index[j]);
if ( j == i ) continue; }
hqqqCoin->Fill( qqq.index[i], qqq.index[j]);
}
for( int j = i + 1; j < qqq.multi; j++){ for( int j = i + 1; j < qqq.multi; j++){
for( int k = 0; k < pc.multi; k++){ for( int k = 0; k < pc.multi; k++){
if(pc.index[k]<24 && pc.e[k]>50 ){ // if(qqq.e[i>50]){
hqqqVpcE->Fill( qqq.e[i], pc.e[k] ); hqqqVpcE->Fill( qqq.e[i], pc.e[k] );
// hpcIndexVE->Fill( pc.index[i], pc.e[i] );
hqqqVpcIndex->Fill( qqq.index[i], pc.index[j] ); hqqqVpcIndex->Fill( qqq.index[i], pc.index[j] );
}
// }
}
} }
// } // }
}
// if( qqq.used[i] == true ) continue;
//if( qqq.id[i] == qqq.id[j] && (16 - qqq.ch[i]) * (16 - qqq.ch[j]) < 0 ){ // must be same detector and wedge and ring
if( qqq.id[i] == qqq.id[j] ){ // must be same detector
int chWedge = -1;
int chRing = -1;
if( qqq.ch[i] < qqq.ch[j]){
chRing = qqq.ch[j] - 16;
chWedge = qqq.ch[i];
}else{
chRing = qqq.ch[i];
chWedge = qqq.ch[j] - 16;
}
// printf(" ID : %d , chWedge : %d, chRing : %d \n", qqq.id[i], chWedge, chRing);
double theta = -TMath::Pi()/2 + 2*TMath::Pi()/16/4.*(qqq.id[i]*16 + chWedge +0.5);
double rho = 10.+40./16.*(chRing+0.5);
// if(qqq.e[i]>50){
hqqqPolar->Fill( theta, rho);
// }
// qqq.used[i] = true;
// qqq.used[j] = true;
if( !HitNonZero ){
double x = rho * TMath::Cos(theta);
double y = rho * TMath::Sin(theta);
hitPos.SetXYZ(x, y, 23 + 75 + 30);
HitNonZero = true;
}
}
}
} }
// //======================= PC
ID.clear(); // hanVScatsum->Fill(aE,cE);
int counter=0;
std::vector<std::pair<int, double>> E;
E.clear();
for( int i = 0; i < pc.multi; i ++){
if( pc.e[i] > 100 ) ID.push_back(std::pair<int, int>(pc.id[i], i));
if( pc.e[i] > 100 ) E.push_back(std::pair<int, double>(pc.index[i], pc.e[i]));
hpcIndexVE->Fill( pc.index[i], pc.e[i] );
for( int j = i+1; j < pc.multi; j++){
hpcCoin->Fill( pc.index[i], pc.index[j]);
}
}
// for( size_t i = 0; i < E.size(); i++) printf("%zu | %d %d \n", i, E[i].first, E[i].second );
if( E.size()>=3 ){
int aID = 0;
int cID = 0;
float aE = 0;
float cE = 0;
bool multi_an =false;
// if( ID[0].first < 1 ) {
// aID = pc.ch[ID[0].second];
// cID = pc.ch[ID[1].second];
// }else{
// cID = pc.ch[ID[0].second];
// aID = pc.ch[ID[1].second];
// }
// printf("anode= %d, cathode = %d\n", aID, cID);
// for( int k = 0; k < qqq.multi; k++){
// if(qqq.index[k]==75 && pc.index[k]==2 && pc.e[k]>100){
for(int l=0;l<E.size();l++){
if(E[l].first<24 && E[l].first!=20 && E[l].first!=12){
if(!multi_an){
aE = E[l].second;
}
multi_an=true;
}
else {
cE = E[l].second + cE;
}
}
// }
// }
hanVScatsum->Fill(aE,cE);
if( ID[0].first < 1 ) {
aID = pc.ch[ID[0].second];
cID = pc.ch[ID[1].second];
}else{
cID = pc.ch[ID[0].second];
aID = pc.ch[ID[1].second];
}
if( HitNonZero){ if( HitNonZero){
pw_contr.CalTrack( hitPos, aID, cID); pw_contr.CalTrack( hitPos, aID, cID);
@ -324,7 +376,7 @@ Bool_t Analyzer::Process(Long64_t entry){
} }
}
@ -337,7 +389,7 @@ Bool_t Analyzer::Process(Long64_t entry){
return kTRUE; return kTRUE;
} }
void Analyzer::Terminate(){ void PCGainMatch::Terminate(){
gStyle->SetOptStat("neiou"); gStyle->SetOptStat("neiou");
TCanvas * canvas = new TCanvas("cANASEN", "ANASEN", 2000, 2000); TCanvas * canvas = new TCanvas("cANASEN", "ANASEN", 2000, 2000);
@ -396,7 +448,7 @@ void Analyzer::Terminate(){
// hqqqPolar->Draw("same colz pol"); // hqqqPolar->Draw("same colz pol");
canvas->cd(padID); canvas->cd(padID)->SetGrid(1); canvas->cd(padID); canvas->cd(padID)->SetGrid(1);
// hZProj->Draw();
hanVScatsum->Draw("colz"); hanVScatsum->Draw("colz");
// hAnodeHits->Draw("colz");
// hAnodeMultiplicity->Draw();
} }

View File

@ -1,5 +1,5 @@
#ifndef Analyzer_h #ifndef PCGainMatch_h
#define Analyzer_h #define PCGainMatch_h
#include <TROOT.h> #include <TROOT.h>
#include <TChain.h> #include <TChain.h>
@ -8,7 +8,7 @@
#include "Armory/ClassDet.h" #include "Armory/ClassDet.h"
class Analyzer : public TSelector { class PCGainMatch : public TSelector {
public : public :
TTree *fChain; //!pointer to the analyzed TTree or TChain TTree *fChain; //!pointer to the analyzed TTree or TChain
@ -41,8 +41,8 @@ public :
TBranch *b_pcE; //! TBranch *b_pcE; //!
TBranch *b_pcT; //! TBranch *b_pcT; //!
Analyzer(TTree * /*tree*/ =0) : fChain(0) { } PCGainMatch(TTree * /*tree*/ =0) : fChain(0) { }
virtual ~Analyzer() { } virtual ~PCGainMatch() { }
virtual Int_t Version() const { return 2; } virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree); virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree); virtual void SlaveBegin(TTree *tree);
@ -57,13 +57,13 @@ public :
virtual void SlaveTerminate(); virtual void SlaveTerminate();
virtual void Terminate(); virtual void Terminate();
ClassDef(Analyzer,0); ClassDef(PCGainMatch,0);
}; };
#endif #endif
#ifdef Analyzer_cxx #ifdef PCGainMatch_cxx
void Analyzer::Init(TTree *tree){ void PCGainMatch::Init(TTree *tree){
// Set branch addresses and branch pointers // Set branch addresses and branch pointers
if (!tree) return; if (!tree) return;
@ -95,18 +95,18 @@ void Analyzer::Init(TTree *tree){
} }
Bool_t Analyzer::Notify(){ Bool_t PCGainMatch::Notify(){
return kTRUE; return kTRUE;
} }
void Analyzer::SlaveBegin(TTree * /*tree*/){ void PCGainMatch::SlaveBegin(TTree * /*tree*/){
TString option = GetOption(); TString option = GetOption();
} }
void Analyzer::SlaveTerminate(){ void PCGainMatch::SlaveTerminate(){
} }

View File

@ -1,27 +1,38 @@
#!/bin/bash #!/bin/bash
if [ "$#" -ne 2 ]; then if [ "$#" -ne 3 ]; then
echo "Usage: $0 runID timeWindow_ns" echo "Usage: $0 runID timeWindow_ns option"
echo "option: 0 - process raw data, 1 - process mapped data"
echo "Exiting..." echo "Exiting..."
exit 1 exit 1
fi fi
runID=$1 runID=$(printf "%03d" $1)
timeWindow=$2 timeWindow=$2
rawFolder=/home/tandem/Desktop/analysis/data option=$3
rootFolder=/home/tandem/Desktop/analysis/data/root_data
rsync -a splitpole@128.186.111.223:/media/nvmeData/ANASEN27Alap/*.fsu /home/tandem/Desktop/analysis/data # rawFolder=/home/tandem/data1/2024_09_17Fap/data
# rawFolder=/mnt/d/17F
# rootFolder=/mnt/d/Remapped_files/17F_data/root_data
# rawFolder=/mnt/data1/vs19g/2024_06_27Al
# rootFolder=/home/vs19g/Desktop/27Al_Data/root_data
rawFolder=/mnt/data1/vs19g/2024_09_17Fap/data
rootFolder=/home/vs19g/Desktop/17F_Data/root_data
fileList=`\ls -1 ${rawFolder}/Run_${runID}_*.fsu` if [ $option -eq 0 ]; then
./EventBuilder ${timeWindow} 0 0 10000000 ${fileList} # rsync -auh --info=progress2 splitpole@128.186.111.223:/media/nvmeData/2024_09_17Fap/*.fsu /home/tandem/data1/2024_09_17Fap/data
outFile=${rawFolder}/*${runID}*${timeWindow}.root fileList=`\ls -1 ${rawFolder}/*Run*_${runID}_*.fsu`
mv -vf ${outFile} ${rootFolder}/. time ./EventBuilder ${timeWindow} 0 0 100000000 ${fileList}
./Mapper ${rootFolder}/*${runID}*${timeWindow}.root outFile=${rawFolder}/*${runID}*${timeWindow}.root
root "processRun.C(\"${rootFolder}/Run_${runID}_mapped.root\")" mv -vf ${outFile} ${rootFolder}/.
time ./Mapper ${rootFolder}/*${runID}*${timeWindow}.root
fi
# root "processRun.C(\"${rootFolder}/Run_${runID}_mapped.root\")"

167
QQQ_Calcheck.C Normal file
View File

@ -0,0 +1,167 @@
#define QQQ_Calcheck_cxx
#include <TH2.h>
#include <TF1.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TMath.h>
#include <TCutG.h>
#include <fstream>
#include <utility>
#include <algorithm>
#include "Armory/HistPlotter.h"
#include "TVector3.h"
#include "QQQ_Calcheck.h"
TH2F *hQQQFVB;
HistPlotter *plotter;
int padID = 0;
TCutG *cut;
std::map<std::tuple<int, int, int>, std::vector<std::pair<double, double>>> dataPoints;
bool qqqEcut = false;
// Gain Arrays
const int MAX_QQQ = 4;
const int MAX_RING = 16;
const int MAX_WEDGE = 16;
double qqqwGain[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
double qqqrGain[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
bool qqqwGainValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
bool qqqrGainValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
double qqqCalib[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
bool qqqCalibValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
void QQQ_Calcheck::Begin(TTree * /*tree*/)
{
plotter = new HistPlotter("Cal_checkQQQ.root", "TFILE");
// ----------------------- Load QQQ Gains
{
std::string filename = "qqq_GainMatch.dat";
std::ifstream infile(filename);
if (!infile.is_open())
{
std::cerr << "Error opening " << filename << "!" << std::endl;
}
else
{
int det, ring, wedge;
double gainw,gainr;
while (infile >> det >> ring >> wedge >> gainw>> gainr)
{
qqqwGain[det][ring][wedge] = gainw;
// qqqrGain[det][ring][wedge] = gainr;
qqqwGainValid[det][ring][wedge] = (gainw > 0);
// qqqrGainValid[det][ring][wedge] = (gainr > 0);
}
infile.close();
std::cout << "Loaded QQQ gains from " << filename << std::endl;
}
}
// ----------------------- Load QQQ Calibrations
{
std::string filename = "qqq_Calib.dat";
std::ifstream infile(filename);
if (!infile.is_open())
{
std::cerr << "Error opening " << filename << "!" << std::endl;
}
else
{
int det, ring, wedge;
double slope;
while (infile >> det >> ring >> wedge >> slope)
{
qqqCalib[det][ring][wedge] = slope;
qqqCalibValid[det][ring][wedge] = (slope > 0);
}
infile.close();
std::cout << "Loaded QQQ calibrations from " << filename << std::endl;
}
}
}
Bool_t QQQ_Calcheck::Process(Long64_t entry)
{
b_qqqMulti->GetEntry(entry);
b_qqqID->GetEntry(entry);
b_qqqCh->GetEntry(entry);
b_qqqE->GetEntry(entry);
b_qqqT->GetEntry(entry);
qqq.CalIndex();
for (int i = 0; i < qqq.multi; i++)
{
for (int j = i + 1; j < qqq.multi; j++)
{
if (qqq.e[i] > 100)
qqqEcut = true;
if (qqq.id[i] == qqq.id[j])
{
int chWedge = -1;
int chRing = -1;
float eWedgeRaw = 0.0;
float eWedge = 0.0;
float eWedgeMeV = 0.0;
float eRingRaw = 0.0;
float eRing = 0.0;
float eRingMeV = 0.0;
// plug in gains
if (qqq.ch[i] < 16 && qqq.ch[j] >= 16 && /*qqqrGainValid[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16] &&*/ qqqwGainValid[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16])
{
chWedge = qqq.ch[i];
eWedgeRaw = qqq.e[i];
eWedge = qqq.e[i] * qqqwGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16];
// printf("Wedge E: %.2f Gain: %.4f \n", eWedge, qqqGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16]);
chRing = qqq.ch[j] - 16;
eRingRaw = qqq.e[j];
eRing = qqq.e[j];//* qqqrGain[qqq.id[j]][qqq.ch[j]][qqq.ch[i]-16];
}
else if (qqq.ch[j] < 16 && qqq.ch[i] >= 16/* && qqqrGainValid[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16] */&& qqqwGainValid[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16])
{
chWedge = qqq.ch[j];
eWedge = qqq.e[j] * qqqwGain[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16];
eWedgeRaw = qqq.e[j];
chRing = qqq.ch[i] - 16;
eRing = qqq.e[i];// * qqqrGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16];
eRingRaw = qqq.e[i];
}
else
continue;
// plug in calibrations
if (qqqCalibValid[qqq.id[i]][chWedge][chRing])
{
eWedgeMeV = eWedge * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000;
eRingMeV = eRing * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000;
}
else
continue;
// hQQQFVB->Fill(eWedge, eRing);
plotter->Fill2D(Form("hRaw_qqq%d_ring%d_wedge%d", qqq.id[i], chRing, chWedge), 400, 0, 8000, 400, 0, 8000, eWedgeRaw, eRingRaw, "ERaw");
plotter->Fill2D(Form("hGM_qqq%d_ring%d_wedge%d", qqq.id[i], chRing, chWedge), 400, 0, 16000, 400, 0, 16000, eWedge, eRing, "EGM");
plotter->Fill2D(Form("hCal_qqq%d_ring%d_wedge%d", qqq.id[i], chRing, chWedge), 400, 0, 10, 400, 0, 10, eWedgeMeV, eRingMeV, "ECal");
if(eWedgeRaw >1500 && eRingRaw>1500 )
plotter->Fill2D(Form("hCal_cut_qqq%d_ring%d_wedge%d", qqq.id[i], chRing, chWedge), 400, 0, 10, 400, 0, 10, eWedgeMeV, eRingMeV, "ECal_cut");
plotter->Fill2D(Form("hRCal_qqq%d", qqq.id[i]), 16, 0, 15, 1000, 0, 30, chRing, eRingMeV, "RingCal");
plotter->Fill2D(Form("hWCal_qqq%d", qqq.id[i]), 16, 0, 15, 1000, 0, 30, chWedge, eWedgeMeV, "WedgeCal");
plotter->Fill2D("hRawQQQ", 4000, 0, 8000, 4000, 0, 8000, eWedgeRaw, eRingRaw);
plotter->Fill2D("hGMQQQ", 4000, 0, 8000, 4000, 0, 8000, eWedge, eRing);
plotter->Fill2D("hCalQQQ", 4000, 0, 10, 4000, 0, 10, eWedgeMeV, eRingMeV);
}
}
}
return kTRUE;
}
void QQQ_Calcheck::Terminate()
{
plotter->FlushToDisk();
std::cout << "Calibration check file for 2D QQQ histogram saved.\n";
}

114
QQQ_Calcheck.h Normal file
View File

@ -0,0 +1,114 @@
#ifndef QQQ_Calcheck_h
#define QQQ_Calcheck_h
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TSelector.h>
#include "Armory/ClassDet.h"
class QQQ_Calcheck : public TSelector {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
// Fixed size dimensions of array or collections stored in the TTree if any.
// Declaration of leaf types
Det sx3;
Det qqq;
Det pc ;
ULong64_t evID;
UInt_t run;
// List of branches
TBranch *b_eventID; //!
TBranch *b_run; //!
TBranch *b_sx3Multi; //!
TBranch *b_sx3ID; //!
TBranch *b_sx3Ch; //!
TBranch *b_sx3E; //!
TBranch *b_sx3T; //!
TBranch *b_qqqMulti; //!
TBranch *b_qqqID; //!
TBranch *b_qqqCh; //!
TBranch *b_qqqE; //!
TBranch *b_qqqT; //!
TBranch *b_pcMulti; //!
TBranch *b_pcID; //!
TBranch *b_pcCh; //!
TBranch *b_pcE; //!
TBranch *b_pcT; //!
QQQ_Calcheck(TTree * /*tree*/ =0) : fChain(0) { }
virtual ~QQQ_Calcheck() { }
virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree);
virtual void Init(TTree *tree);
virtual Bool_t Notify();
virtual Bool_t Process(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
virtual void SetOption(const char *option) { fOption = option; }
virtual void SetObject(TObject *obj) { fObject = obj; }
virtual void SetInputList(TList *input) { fInput = input; }
virtual TList *GetOutputList() const { return fOutput; }
virtual void SlaveTerminate();
virtual void Terminate();
ClassDef(QQQ_Calcheck,0);
};
#endif
#ifdef QQQ_Calcheck_cxx
void QQQ_Calcheck::Init(TTree *tree){
// Set branch addresses and branch pointers
if (!tree) return;
fChain = tree;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("evID", &evID, &b_eventID);
fChain->SetBranchAddress("run", &run, &b_run);
sx3.SetDetDimension(24,12);
qqq.SetDetDimension(4,32);
pc.SetDetDimension(2,24);
fChain->SetBranchAddress("sx3Multi", &sx3.multi, &b_sx3Multi);
fChain->SetBranchAddress("sx3ID", &sx3.id, &b_sx3ID);
fChain->SetBranchAddress("sx3Ch", &sx3.ch, &b_sx3Ch);
fChain->SetBranchAddress("sx3E", &sx3.e, &b_sx3E);
fChain->SetBranchAddress("sx3T", &sx3.t, &b_sx3T);
fChain->SetBranchAddress("qqqMulti", &qqq.multi, &b_qqqMulti);
fChain->SetBranchAddress("qqqID", &qqq.id, &b_qqqID);
fChain->SetBranchAddress("qqqCh", &qqq.ch, &b_qqqCh);
fChain->SetBranchAddress("qqqE", &qqq.e, &b_qqqE);
fChain->SetBranchAddress("qqqT", &qqq.t, &b_qqqT);
fChain->SetBranchAddress("pcMulti", &pc.multi, &b_pcMulti);
fChain->SetBranchAddress("pcID", &pc.id, &b_pcID);
fChain->SetBranchAddress("pcCh", &pc.ch, &b_pcCh);
fChain->SetBranchAddress("pcE", &pc.e, &b_pcE);
fChain->SetBranchAddress("pcT", &pc.t, &b_pcT);
}
Bool_t QQQ_Calcheck::Notify(){
return kTRUE;
}
void QQQ_Calcheck::SlaveBegin(TTree * /*tree*/){
TString option = GetOption();
}
void QQQ_Calcheck::SlaveTerminate(){
}
#endif // #ifdef QQQ_Calcheck_cxx

238
README.md Normal file
View File

@ -0,0 +1,238 @@
# ANASEN Analysis
Analysis code for the **Array for Nuclear Astrophysics and Structure with Exotic Nuclei (ANASEN)** detector at FSU. Processes raw .fsu data through event building, channel mapping, calibration, and physics-level vertex reconstruction for transfer reaction experiments.
---
## Detector Overview
| Detector | Type | Role |
|----------|------|------|
| **SX3** | Double-sided silicon strip (barrel, ~88 mm radius) | Energy and Z-position of recoils/ejectiles |
| **QQQ** | Annular silicon (forward, z = 100 mm) | Energy and polar angle of forward-going particles |
| **PC** | Helical proportional counter | dE and azimuthal/Z position via 24 anode + 24 cathode wires |
The PC uses 24 twisted anode wires and 24 cathode wires. Wire geometry, crossover positions, pseudo-wire interpolation, and track-plane intersection are all handled by `Armory/ClassPW.h`.
---
## Full Analysis Chain
```
Raw .fsu files (FSU digitizer output)
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. EVENT BUILDING │
│ Binary: EventBuilder (Armory/EventBuilder.cpp) │
│ Script: buildEvents.sh or ProcessRun.sh <run> <tw> 0 │
│ Input : *.fsu files │
│ Output: Run_NNN_<timeWindow>ns.root (raw, unmapped TTree) │
│ Hits within a configurable time window are grouped as events. │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 3. PRE-ANALYSIS CHECKS (optional) │
│ Macro: PreAnalysis.C │
│ Plots raw rates and energy spectra per channel from unmapped │
│ data — useful for identifying dead/noisy channels before │
│ mapping. │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. CHANNEL MAPPING │
│ Binary: Mapper (Armory/Mapper.cpp) │
│ Script: ProcessRun.sh <run> <tw> 0 (calls Mapper internally) │
│ Config: mapping.h │
│ Input : Eventbuilt ROOT tree │
│ Output: Run_NNN_mapped.root │
│ Translates hardware (digitizer SN, channel) to logical │
│ detector identity (SX3/QQQ/PC, strip/wire number). │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 4. CALIBRATION │
│ │
| SX3 — two-pass procedure: │
│ Pass 1 — Left/Right matching (sx3cal/LRFit.C) │
│ │ Start with unity gains: │
│ │ LRFit.C fits the left/right charge ratio │
│ │ Collate per-detector results into a single rightgains.dat │
| │ │
│ Pass 2 — Back/Front gain matching (sx3cal/EXFit.C) │
│ │ Run on data that is unity-gain sorted but L/R matched │
│ │ EXFit.C : │
│ │ 1) gain-matches the back strips (backgains.dat) │
│ │ 2) corrects dynamic range non-linearity in the fronts │
│ │ (frontgains.dat) │
│ │ Run for every detector, collate into master backgains.dat │
│ │ and frontgains.dat. │
│ │ |
│ ├── GainMatchQQQ.C │
│ │ QQQ ring/wedge gain matching │
│ │ Output: qqq_GainMatch.dat │
│ ├── CalibrationQQQ.C │
│ │ Final absolute energy calibration for all detectors │
│ │ Output: qqq_Calib.dat │
│ ├── PCGainMatch.C │
│ │ PC anode and cathode gain matching │
│ │ Output: slope_intercept_*.dat │
│ ├── FitHistogramsWithTSpectrum_Sequential_Improved.C │
│ │ Automated peak finding on PC wire spectra │
│ │ done separately for anodes and cathodes then combined │
│ │ (TSpectrum-based; writes centroids for gain match) │
│ └──QQQ_Calcheck.C │
│ Verifies QQQ calibration against known sources │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 5. VERTEX RECONSTRUCTION (MakeVertex) │
│ Macro : MakeVertex.C (ROOT TSelector) │
│ Batch : run_sx3.sh (choose dataset, wireflip and offset) │
│ Input : Run_NNN_mapped.root │
│ Output: result_runNNN.root (calibrated TTree │
│ + diagnostic histograms) │
│ Applies energy calibrations, reconstructs PC hit positions │
│ (anode energy + cathode charge division), clusters wires, │
│ and builds SX3/QQQ/PC event objects. │
│ 3D track-reconstruction diagnostics using │
│ PC wire geometry and Si hit positions. │
└─────────────────────────────────────────────────────────────────┘
```
---
## Channel Mapping (`mapping.h` / `mapping_alpha.h`)
The Mapper binary reads the raw TTree (digitizer serial number + channel) and rewrites it with logical detector labels. `mapping.h` is used for standard beam runs; `mapping_alpha.h` for source/alpha calibration runs where the electronics configuration differs. The active mapping is selected by editing the `#include` at the top of `Armory/Mapper.cpp` before building.
`PrintMapping()` (defined in the mapping header) prints the full channel table at runtime for verification.
---
## MakeVertex — Vertex Reconstruction
`MakeVertex.C` is a ROOT `TSelector` that loops over the analyzed event tree and fills diagnostic and physics histograms. It loads energy-loss lookup tables from `eloss_calculations/` and uses `Armory/Kinematics.h` for two-body reaction kinematics.
### Diagnostic Section Toggles
Comment out any `#define` at the top of `MakeVertex.C` to skip that block at compile time:
```cpp
#define DIAG_WIREMULT // anode/cathode cluster multiplicity plots
#define DIAG_1WIRE // raw per-wire dE vs Si (no PC required)
#define DIAG_PC_SX3 // PC-SX3 coincidence analysis
#define DIAG_1A0C_SX3 // 1A0C single-wire vertex with SX3
#define DIAG_1A0C_QQQ // 1A0C single-wire vertex with QQQ
#define DIAG_NA0C_SX3 // nA0C (n>=2) pseudo-wire vertex with SX3
#define DIAG_NA0C_QQQ // nA0C (n>=2) pseudo-wire vertex with QQQ
#define DIAG_PC_QQQ // PC-QQQ coincidence analysis
```
### Histogram Output Folders
| ROOT Folder | Content |
|-------------|---------|
| `wiremult` | Anode/cathode cluster size and multiplicity matrices |
| `1wire` | Raw single-wire dE vs SX3/QQQ energy and phi correlations |
| `hTiming` | PC-Si timing spectra |
| `hPCZSX3` | PC-Z reconstruction with SX3 coincidence |
| `hPCzQQQ` | PC-Z projection with QQQ coincidence |
| `1A0C`,`2A0C`, `3A0C`, … | n anodes (n≥1), 0 cathode: pseudo-wire vertex + excitation spectra |
| `ainterp_noc` | Pseudo-wire interpolation diagnostics (no cathode gate) |
| `phicut` | PC-QQQ with phi coincidence gate |
### Vertex Reconstruction Methods
**nA0C (n ≥ 1 anodes, `DIAG_NA0C_SX3/QQQ`):** All anode clusters are flattened and passed to `GetPseudoWire()` to produce an energy-weighted average wire. `getClosestWirePosAtWirePhi()` then finds the point on that pseudo-wire at the Si phi. Histograms land in a folder named `{n}A0C` (e.g. `2A0C`).
---
## Energy Loss (`eloss_calculations/`)
Lookup tables pre-computed with [pycatima](https://github.com/hrosiak/pycatima) for the isobutane/helium fill gas at 250 Torr. Tables cover protons, alphas, aluminum beam, fluorine, and oxygen. `Eloss.py` regenerates the tables; `make_eloss_table.C` is a ROOT-based alternative generator.
The `cm_to_MeV` / `MeV_to_cm` TGraph pairs loaded in `MakeVertex.C` provide fast range–energy conversion for correcting energy loss in the Si detectors.
---
## Geometry Utilities
| File | Purpose |
|------|---------|
| `grid_generate.py` | Generates `detector_geometry.dat` — calculates SX3, QQQ, and PC wire azimuthal angles from first principles given detector radii and strip positions |
| `shadowplay.py` | Exports ANASEN geometry (wires, SX3, QQQ) as a VTK file + `anasen_labels.csv` for visualisation in ParaView |
| `detector_geometry.dat` | Pre-generated geometry reference (SX3 strip angles, wire positions) |
| `anasen_labels.csv` | Label table for ParaView geometry display |
---
## FEM Simulations (`anasen_fem/`)
Finite-element simulations of the PC electric field using gmsh (meshing), Elmer (FEM solver), and ParaView (visualisation). See `anasen_fem/README.md` for full setup and installation instructions.
```bash
cd anasen_fem
python3 run.py # mesh → FEM solve → field extraction → ParaView output
```
---
## Batch Processing Scripts
| Script | Purpose |
|--------|---------|
| `buildEvents.sh <run> <tw>` | Build events from raw .fsu for a single run |
| `ProcessRun.sh <run> <tw> <opt>` | Full single-run pipeline: event build (opt=0) or analysis (opt=1) |
| `BatchProcess.sh` | Parallel batch processing over a run range via GNU parallel |
| `process_mapped_run.sh <start> <end>` | Run `TrackRecon.C` in parallel over a range of mapped files |
| `run_sx3.sh/run_27Al.sh/run_17F.sh` | Run `VertexRecon.C` in parallel over a range of mapped files and hAdds them for analysis|
---
## Dependencies
- [ROOT](https://root.cern) ≥ 6.x (TSelector, TChain, TVector3, TF1, TGraph, TSpectrum)
- [GNU parallel](https://www.gnu.org/software/parallel/) — for batch scripts
- [pycatima](https://github.com/hrosiak/pycatima) — for regenerating energy-loss tables
- gmsh + Elmer + ParaView — for FEM simulations only
---
## Key Files Reference
| File | Purpose |
|------|---------|
| `mapping.h` / `mapping_alpha.h` | Hardware→logical channel mapping (beam / alpha-source configs) |
| `Armory/EventBuilder.cpp` | Time-window coincidence event builder (compiled binary) |
| `Armory/Mapper.cpp` | Channel remapper: SN+ch → detector ID (compiled binary) |
| `PreAnalysis.C / .h` | Raw rate and energy checks on mapped data |
| `sx3cal/EXFit.C`, `EXFit2.C` | SX3 front/back gain coefficient extraction |
| `sx3cal/LRFit.C` | SX3 left-right position calibration |
| `sx3cal/{17F,27Al}/` | Per-experiment gain coefficient files (frontgains, backgains, rightgains) |
| `GainMatchQQQ.C` | QQQ gain matching |
| `Calibration.C / .h` | Absolute energy calibration |
| `QQQ_Calcheck.C` | QQQ calibration verification |
| `PCGainMatch.C` | PC anode/cathode gain matching |
| `FitHistogramsWithTSpectrum_Sequential_Improved.C` | Automated PC anode peak fitting |
| `Analyzer.C / .h` | Event-level clustering and PC hit reconstruction, (older in need of rehaul)|
| `Analysis.C` | TChain wrapper to run Analyzer over a run range |
| `processRun.C` | Single-file wrapper to run Analyzer on one ROOT file |
| `MakeVertex.C / .h` | Vertex reconstruction and physics histogram production |
| `TrackRecon.C / .h` | Alternate to VertexRecon, to track changes through code, eventaully plan to clean up one for actual data analysis |
| `RunTimeSummary.C` | Run-by-run timing/rate summary across a run range |
| `Armory/ClassPW.h` | PC wire geometry: crossovers, pseudo-wire, track-plane intersection |
| `Armory/Kinematics.h/.cpp` | Two-body reaction kinematics (excitation energy, Q-value) |
| `Armory/HistPlotter.h` | Histogram management with named ROOT folders |
| `Armory/SX3Geom.h` | SX3 detector geometry |
| `Armory/PC_StepLadder_Correction.h` | PC Z-position slope correction |
| `eloss_calculations/Eloss.py` | Energy-loss table generator (pycatima) |
| `grid_generate.py` | Generates `detector_geometry.dat` from first principles |
| `shadowplay.py` | Exports ANASEN geometry to VTK + CSV for ParaView |
| `detector_geometry.dat` | Pre-generated detector geometry reference |
| `anasen_labels.csv` | Label table for ParaView geometry visualisation |
| `anasen_fem/` | FEM electric field simulations for the PC |

140
RunTimeSummary.C Normal file
View File

@ -0,0 +1,140 @@
#include <TFile.h>
#include <TH1.h>
#include <TH2.h>
#include <TString.h>
#include <TSystem.h>
#include <TCanvas.h>
#include <iostream>
void RunTimeSummary(int startRun, int endRun)
{
TString fileDir = "/mnt/d/Remapped_files/17F_data/root_data/";
TString histName = "AnodeQQQ_Time";
TString filePattern = "Run_%03d_mapped_histograms.root";
TString filePatternAlt = "ProtonRun_%d_mapped_histograms.root";
TString filePatternAlt2 = "Source_%d_mapped_histograms.root";
int nBinsTime = 0;
double timeMin = 0, timeMax = 0;
bool foundRef = false;
for (int r = startRun; r <= endRun; r++)
{
TString tempName;
// 1. Try Pattern 1: Run_XXX...
tempName = fileDir + Form(filePattern, r);
if (gSystem->AccessPathName(tempName))
{ // Returns true if MISSING
// 2. Try Pattern 2: ProtonRun_X...
tempName = fileDir + Form(filePatternAlt, r);
if (gSystem->AccessPathName(tempName))
{
// 3. Try Pattern 3: Source_X...
tempName = fileDir + Form(filePatternAlt2, r);
if (gSystem->AccessPathName(tempName))
{
// All 3 patterns failed. Skip this run.
continue;
}
}
}
// If we get here, 'tempName' holds the valid filename that was found
TFile *fTemp = TFile::Open(tempName);
if (!fTemp || fTemp->IsZombie())
{
if (fTemp)
delete fTemp;
continue;
}
TH1F *hRef = (TH1F *)fTemp->Get(histName);
if (hRef)
{
nBinsTime = hRef->GetNbinsX();
timeMin = hRef->GetXaxis()->GetXmin();
timeMax = hRef->GetXaxis()->GetXmax();
foundRef = true;
delete hRef;
fTemp->Close();
delete fTemp;
printf("Reference found in Run %d: %d bins, Range [%.1f, %.1f]\n", r, nBinsTime, timeMin, timeMax);
break;
}
fTemp->Close();
delete fTemp;
}
if (!foundRef)
{
printf("Error: No valid histograms found in the entire range. Exiting.\n");
return;
}
int nRuns = endRun - startRun + 1;
TH2F *hSummary = new TH2F("hSummary",
Form("Timing Summary (Runs %d-%d);Timing;Run Number", startRun, endRun),
nBinsTime, timeMin, timeMax,
nRuns, startRun, endRun + 1);
for (int run = startRun; run <= endRun; run++)
{
TString filename = fileDir + Form(filePattern, run);
if (gSystem->AccessPathName(filename))
continue;
TFile *fin = TFile::Open(filename);
if (!fin || fin->IsZombie())
{
if (fin)
delete fin;
continue;
}
TH1F *hin = (TH1F *)fin->Get(histName);
if (hin)
{
// Determine which ROW (Y-bin) corresponds to this Run
// Note: ROOT bins start at 1.
// If startRun=10 and run=10 -> binY=1.
int binY_Run = run - startRun + 1;
// Loop through the Time bins (X-bins in the 1D hist)
for (int binX_Time = 1; binX_Time <= hin->GetNbinsX(); binX_Time++)
{
double content = hin->GetBinContent(binX_Time);
// Copy content to: (Time, Run)
if (content > 0)
{
hSummary->SetBinContent(binX_Time, binY_Run, content);
}
}
delete hin;
}
fin->Close();
delete fin;
if ((run - startRun) % 10 == 0)
printf("Stitched Run %d...\n", run);
}
TFile *fOut = new TFile("SummaryPlot.root", "RECREATE");
hSummary->Write();
TCanvas *c1 = new TCanvas("c1", "Time Summary Plot", 1000, 800);
hSummary->SetStats(0);
hSummary->Draw("COLZ");
printf("Done! Saved to SummaryPlot.root\n");
}

File diff suppressed because it is too large Load Diff

141
TrackRecon.h Normal file
View File

@ -0,0 +1,141 @@
#ifndef TrackRecon_h
#define TrackRecon_h
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TSelector.h>
#include <vector>
#include <utility>
#include <unordered_map>
#include <tuple>
#include "Armory/ClassDet.h"
#include "Armory/ClassPW.h"
class TrackRecon : public TSelector
{
public:
TTree *fChain; //! pointer to the analyzed TTree or TChain
// Declaration of leaf types
Det sx3;
Det qqq;
Det pc;
Det misc;
ULong64_t evID;
UInt_t run;
// List of branches
TBranch *b_eventID; //!
TBranch *b_run; //!
TBranch *b_sx3Multi; //!
TBranch *b_sx3ID; //!
TBranch *b_sx3Ch; //!
TBranch *b_sx3E; //!
TBranch *b_sx3T; //!
TBranch *b_qqqMulti; //!
TBranch *b_qqqID; //!
TBranch *b_qqqCh; //!
TBranch *b_qqqE; //!
TBranch *b_qqqT; //!
TBranch *b_pcMulti; //!
TBranch *b_pcID; //!
TBranch *b_pcCh; //!
TBranch *b_pcE; //!
TBranch *b_pcT; //!
TBranch *b_miscMulti; //!
TBranch *b_miscID; //!
TBranch *b_miscCh; //!
TBranch *b_miscE; //!
TBranch *b_miscT; //!
TBranch *b_miscTf; //!
// 1. Geometry Cache
Coord Crossover[24][24][2];
// 2. Persistent Vectors (REQUIRED for the optimized .cxx to work)
std::vector<std::pair<int, double>> anodeHits;
std::vector<std::pair<int, double>> cathodeHits;
std::vector<std::pair<int, double>> corrcatMax;
std::vector<std::pair<int, double>> corranoMax;
std::vector<double> cathodeTimes;
std::vector<double> anodeTimes;
std::unordered_map<int, std::tuple<int, double, double>> aWireEvents, cWireEvents;
TrackRecon(TTree * /*tree*/ = 0) : fChain(0) {}
virtual ~TrackRecon() {}
virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree);
virtual void Init(TTree *tree);
virtual Bool_t Notify();
virtual Bool_t Process(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
virtual void SetOption(const char *option) { fOption = option; }
virtual void SetObject(TObject *obj) { fObject = obj; }
virtual void SetInputList(TList *input) { fInput = input; }
virtual TList *GetOutputList() const { return fOutput; }
virtual void SlaveTerminate();
virtual void Terminate();
void OldAnalysis();
ClassDef(TrackRecon, 0);
};
#endif
#ifdef TrackRecon_cxx
void TrackRecon::Init(TTree *tree)
{
if (!tree)
return;
fChain = tree;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("evID", &evID, &b_eventID);
fChain->SetBranchAddress("run", &run, &b_run);
sx3.SetDetDimension(24, 12);
qqq.SetDetDimension(4, 32);
pc.SetDetDimension(2, 24);
fChain->SetBranchAddress("sx3Multi", &sx3.multi, &b_sx3Multi);
fChain->SetBranchAddress("sx3ID", &sx3.id, &b_sx3ID);
fChain->SetBranchAddress("sx3Ch", &sx3.ch, &b_sx3Ch);
fChain->SetBranchAddress("sx3E", &sx3.e, &b_sx3E);
fChain->SetBranchAddress("sx3T", &sx3.t, &b_sx3T);
fChain->SetBranchAddress("qqqMulti", &qqq.multi, &b_qqqMulti);
fChain->SetBranchAddress("qqqID", &qqq.id, &b_qqqID);
fChain->SetBranchAddress("qqqCh", &qqq.ch, &b_qqqCh);
fChain->SetBranchAddress("qqqE", &qqq.e, &b_qqqE);
fChain->SetBranchAddress("qqqT", &qqq.t, &b_qqqT);
fChain->SetBranchAddress("pcMulti", &pc.multi, &b_pcMulti);
fChain->SetBranchAddress("pcID", &pc.id, &b_pcID);
fChain->SetBranchAddress("pcCh", &pc.ch, &b_pcCh);
fChain->SetBranchAddress("pcE", &pc.e, &b_pcE);
fChain->SetBranchAddress("pcT", &pc.t, &b_pcT);
fChain->SetBranchAddress("miscMulti", &misc.multi, &b_miscMulti);
fChain->SetBranchAddress("miscID", &misc.id, &b_miscID);
fChain->SetBranchAddress("miscCh", &misc.ch, &b_miscCh);
fChain->SetBranchAddress("miscE", &misc.e, &b_miscE);
fChain->SetBranchAddress("miscT", &misc.t, &b_miscT);
fChain->SetBranchAddress("miscF", &misc.tf, &b_miscTf);
}
Bool_t TrackRecon::Notify()
{
return kTRUE;
}
void TrackRecon::SlaveBegin(TTree * /*tree*/)
{
// TString option = GetOption();
}
void TrackRecon::SlaveTerminate()
{
}
#endif // #ifdef TrackRecon_cxx

187
anasen_fem/1dpotplot.py Executable file
View File

@ -0,0 +1,187 @@
#!/home/vsitaraman/ParaView-6.1.0-RC1-MPI-Linux-Python3.12-x86_64/bin/pvbatch
import sys
import numpy as np
from paraview.simple import *
import paraview.servermanager as sm
from paraview.vtk.numpy_interface import dataset_adapter as dsa
# ==========================================
# COMMAND LINE ARGUMENTS
# ==========================================
if len(sys.argv) < 2:
print("Usage: pvbatch 1dpotplot.py <z_locus in mm>")
sys.exit(1)
z_loc = float(sys.argv[1])
INPUT_FILE = f"wires2d/elfield_anasen_t0001.vtu"
OUTPUT_CSV = f"anode_to_cathode_1d_{z_loc}.csv"
OUTPUT_IMAGE = f"1D_Variation_Plot_{z_loc}.png"
print(f"--- Starting 1D Potential Extraction for Z = {z_loc} mm ---")
# ==========================================
# 1. EXACT GEOMETRIC CALCULATION
# ==========================================
print("Calculating theoretical wire coordinates...")
wireShift = 4.0
k = 2 * np.pi / 24.0
offset_a1 = -10.0 * k
offset_c1 = -5.5 * k
offset_a2 = offset_a1 + (wireShift * k)
offset_c2 = offset_c1 - (wireShift * k)
t = (z_loc + 174.3) / (2 * 174.3)
# Anode 0 theoretical position
xa_loc = (37.0 * np.cos(offset_a1)) + t * (37.0 * np.cos(offset_a2) - 37.0 * np.cos(offset_a1))
ya_loc = (37.0 * np.sin(offset_a1)) + t * (37.0 * np.sin(offset_a2) - 37.0 * np.sin(offset_a1))
# All Cathodes theoretical positions
xc1_all = np.array([42.0 * np.cos(k * i + offset_c1) for i in range(24)])
yc1_all = np.array([42.0 * np.sin(k * i + offset_c1) for i in range(24)])
xc2_all = np.array([42.0 * np.cos(k * i + offset_c2) for i in range(24)])
yc2_all = np.array([42.0 * np.sin(k * i + offset_c2) for i in range(24)])
xc_loc_all = xc1_all + t * (xc2_all - xc1_all)
yc_loc_all = yc1_all + t * (yc2_all - yc1_all)
# Nearest Cathode theoretical position
distances = np.sqrt((xc_loc_all - xa_loc)**2 + (yc_loc_all - ya_loc)**2)
nearest_c_idx = np.argmin(distances)
xc_loc = xc_loc_all[nearest_c_idx]
yc_loc = yc_loc_all[nearest_c_idx]
# Theoretical targets in meters
math_anode = np.array([xa_loc / 1000.0, ya_loc / 1000.0, 0.0])
math_cathode = np.array([xc_loc / 1000.0, yc_loc / 1000.0, 0.0])
# ==========================================
# 2. MESH DATA SNAPPING (Electrode-Constrained)
# ==========================================
print(f"Loading VTU file: {INPUT_FILE} to snap to electrode nodes...")
reader = XMLUnstructuredGridReader(FileName=[INPUT_FILE])
UpdatePipeline()
# Fetch data to Python
raw_data = sm.Fetch(reader)
wrapped_data = dsa.WrapDataObject(raw_data)
pts = wrapped_data.Points
pot = wrapped_data.PointData['potential']
print("\nPotential range:")
print(" min =", np.min(pot))
print(" max =", np.max(pot))
# -------------------------------------------------
# Find actual electrode nodes
# -------------------------------------------------
anode_candidates = np.where(pot > 640.0)[0]
if len(anode_candidates) == 0:
raise RuntimeError("No anode nodes found near 650 V")
cathode_candidates = np.where(np.abs(pot) < 1.0)[0]
if len(cathode_candidates) == 0:
raise RuntimeError("No cathode nodes found near 0 V")
print(f"Found {len(anode_candidates)} anode nodes")
print(f"Found {len(cathode_candidates)} cathode nodes")
# -------------------------------------------------
# Snap theoretical anode location to nearest
# actual anode node
# -------------------------------------------------
anode_dist = np.linalg.norm(
pts[anode_candidates] - math_anode,
axis=1
)
anode_idx = anode_candidates[np.argmin(anode_dist)]
true_anode_pos = pts[anode_idx]
true_anode_pot = pot[anode_idx]
# -------------------------------------------------
# Snap theoretical cathode location to nearest
# actual cathode node
# -------------------------------------------------
cathode_dist = np.linalg.norm(
pts[cathode_candidates] - math_cathode,
axis=1
)
cathode_idx = cathode_candidates[np.argmin(cathode_dist)]
true_cathode_pos = pts[cathode_idx]
true_cathode_pot = pot[cathode_idx]
# -------------------------------------------------
# Diagnostics
# -------------------------------------------------
anode_snap_error = np.linalg.norm(
true_anode_pos - math_anode
)
cathode_snap_error = np.linalg.norm(
true_cathode_pos - math_cathode
)
print("\nSelected electrode nodes:")
print(f"Anode:")
print(f" position = {true_anode_pos}")
print(f" potential = {true_anode_pot:.3f} V")
print(f" distance = {anode_snap_error*1e6:.1f} um")
print(f"\nCathode:")
print(f" position = {true_cathode_pos}")
print(f" potential = {true_cathode_pot:.3f} V")
print(f" distance = {cathode_snap_error*1e6:.1f} um")
# ==========================================
# 3. PARAVIEW EXTRACTION & PLOTTING
# ==========================================
print("Extracting data along the snapped line...")
plot_over_line = PlotOverLine(Input=reader)
# Apply the SNAPPED coordinates (converted to standard Python lists)
plot_over_line.Point1 = true_anode_pos.tolist()
plot_over_line.Point2 = true_cathode_pos.tolist()
plot_over_line.Resolution = 1000
SaveData(OUTPUT_CSV, proxy=plot_over_line)
print("Rendering plot...")
line_chart_view = CreateView('XYChartView')
line_chart_view.ViewSize = [1000, 600]
line_chart_view.ChartTitle = f'Potential & E-Field: Anode to Cathode (Z = {z_loc} mm)'
line_chart_view.LeftAxisTitle = 'Potential (V)'
line_chart_view.BottomAxisTitle = 'Distance from Anode (m)'
line_display = Show(plot_over_line, line_chart_view)
# Tell ParaView to draw BOTH variables
# line_display.SeriesVisibility = ['potential', 'electric field_Magnitude']
line_display.SeriesVisibility = ['potential']
# Style Potential (Red)
line_display.SeriesColor = ['potential', '1.0', '0.0', '0.0']
line_display.SeriesLineThickness = ['potential', '3']
# # Style Electric Field (Blue, Right Axis)
# line_display.SeriesColor = ['electric field_Magnitude', '0.0', '0.5', '1.0']
# line_display.SeriesLineThickness = ['electric field_Magnitude', '3']
# line_display.SeriesPlotCorner = ['electric field_Magnitude', '1']
# line_chart_view.RightAxisTitle = 'Electric Field (V/m)'
SaveScreenshot(OUTPUT_IMAGE, view=line_chart_view)
print(f"Saved plot screenshot to: {OUTPUT_IMAGE}")
print("--- Extraction Complete ---")

46
anasen_fem/README.md Executable file
View File

@ -0,0 +1,46 @@
### README for ANASEN fem simulations:
* There are a few iterations of these simulations that already exist. Be sure to also locate and refer to them if necessary.
* Install gmsh and its python api by running (Ubuntu 22.04 LTS)
```
sudo apt install gmsh python3-gmsh
```
* Gmsh gives us the tools to create a meshgrid that samples the 2d space appropriately to plot the field/equipotential lines.
* The output file typically has the .msh extension. This is read as input to Elmer, which is the FEM differential-equation solver.
* Install Elmer via the following steps:
```
sudo add-apt-repository ppa:elmer-csc-ubuntu/elmer-csc-ppa
sudo apt install elmerfem-csc-eg
```
* Install ParaView for visualizations by downloading from the Linux .tar.gz link at https://www.paraview.org/download/
- The current version is tested to work on Paraview 6.1.0. The default version in Ubuntu 22.04 repositories has some trouble with scripting
* v0.0.1, March 10 2026
- 2d simulations of fields only. gmsh for meshing, elmer for fem, paraview to plot
- Before running, open `paraview_plotter.py` to make the bash shebang (#!) point to the location of `pvpython` or `pvbatch`
- `python3 run.py` should run everything in order, and is hopefully all the files are self-documenting
* v0.0.2, September 2026
- Adds the Ramo weighting field and the `E . E_w` dot product for one cathode wire.
- `wires_gmsh2d_bc.py` now cuts the wires into the gas disk with `occ.fragment` instead of `mesh.embed`, so each wire boundary is a real edge of the domain. One cathode (optional 2nd argument, default 1) gets its own physical group, **tag 40**; the other 23 stay in tag 30.
- Two solves, same mesh, identical apart from the potentials:
| file | tag 40 | output |
|---|---|---|
| `wires2d.sif` | 0 V, like every other cathode | `wires2d/elfield_anasen_t0001.vtu` |
| `wires2d_weight.sif` | 1 V, all else 0 V | `wires2d/elfield_weight_t0001.vtu` |
- `dotproduct.py` reads both and writes `wires2d/dotproduct.vtu` with `DotProduct = E . E_w` (V/m^2). It aborts if the node sets differ or if either field is all zeros — both are silent failures otherwise.
- `paraview_dotproduct.py` renders it. `DOT_MIN`/`DOT_MAX` set the colour range and decide whether the picture shows anything.
- `paraview_plotter.py` gains two views: the equipotentials over one quadrant, and streamlines over the same quadrant. Streamlines are drift paths up to diffusion, so they show which wire collects charge from where; `SEED_POTENTIAL` and `SEED_STRIDE` control them.
- Six PNGs per z-locus, archived as before (`<Stem>_z_<count>_<z>[_quarter].png`). `Field_ouput` keeps its typo so the new files sort with the dozen already in `png/`.
- `STAGE` in `run.py`: `1` = mesh + physical solve, `2` = weighting solve + dot product reusing stage 1's mesh, `0` = both. Stage 2 never re-meshes, so it applies to whichever z stage 1 ran last.
- **Do not pass `-autoclean` to ElmerGrid.** It renumbers the physical groups (13/10/20/30/40 become 1/4/5/6/7), so every `Target Bodies`/`Target Boundaries` in the sifs matches nothing, Elmer solves nothing, and the potential comes out identically zero with no error.
- `mesh.recombine()` and `mesh.refine()` are both off: recombination ran over half an hour on the barrel surface without finishing, and refine took the mesh to ~16M nodes.
- Note on the solver stack: both sifs are the same file bar the potentials, so whatever `FluxSolver` does to `Electric Field` it does equally to both and the dot product stays consistent.
* v0.0.3, planned TODO
- Garfield to take Elmer results and perform charge-transport
- Sweep the weighting solve over all 24 cathodes rather than one at a time

2
anasen_fem/clean.sh Executable file
View File

@ -0,0 +1,2 @@
rm -f wires2d.msh
rm -rf wires2d/*

View File

@ -0,0 +1,2 @@
1
13 1.0

148
anasen_fem/dotproduct.py Normal file
View File

@ -0,0 +1,148 @@
#!/usr/bin/env python3
"""Node-by-node dot product of the physical field with a Ramo weighting field.
Reads the two Elmer VTUs from wires2d.sif and wires2d_weight.sif and writes one
carrying DotProduct = E . E_w. E is in V/m and E_w in 1/m (its electrode is
driven to 1 V), so DotProduct is in V/m^2.
By Shockley-Ramo a charge q drifting at v induces i = -q v . E_w, and for
v = mu E that is -q mu (E . E_w). So this map is the induced-current density up
to the constant -q*mu; --scale folds it in. The signs of q and mu differ
between the electron and ion components, so they are left to the caller.
python3 dotproduct.py
python3 dotproduct.py --scale -1.0e-4
"""
import argparse
import sys
import numpy as np
try:
import meshio
except ImportError:
sys.exit("meshio is required: pip install meshio")
def find_array(point_data, wanted, label):
"""Look up a point-data array, ignoring case and spacing.
Elmer lowercases variable names into the VTU and the spelling has varied
between versions, so match loosely and list what is there on failure.
"""
def norm(s):
return "".join(s.lower().split())
target = norm(wanted)
for key in point_data:
if norm(key) == target:
return point_data[key]
sys.exit(
"%s: no point-data array matching %r.\nAvailable arrays: %s"
% (label, wanted, sorted(point_data))
)
def as_vectors(arr, label):
"""Return an (N, ncomp) float array, tolerating flat or 2-component data."""
a = np.asarray(arr, dtype=float)
if a.ndim == 1:
sys.exit("%s: expected a vector field, got a scalar array" % label)
if a.ndim != 2:
sys.exit("%s: expected a 2D array, got shape %s" % (label, a.shape))
return a
def main():
ap = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("--phys", default="wires2d/elfield_anasen_t0001.vtu",
help="VTU from the physical solve (wires2d.sif)")
ap.add_argument("--weight", default="wires2d/elfield_weight_t0001.vtu",
help="VTU from the weighting solve (wires2d_weight.sif)")
ap.add_argument("--out", default="wires2d/dotproduct.vtu",
help="output VTU")
ap.add_argument("--field", default="electric field",
help="name of the electric-field array in both inputs")
ap.add_argument("--scale", type=float, default=None,
help="constant (e.g. -q*mu) multiplying the dot product; "
"writes an extra ScaledDotProduct array")
ap.add_argument("--rtol", type=float, default=0.0,
help="relative tolerance for the node-position check")
ap.add_argument("--atol", type=float, default=1e-12,
help="absolute tolerance (m) for the node-position check")
args = ap.parse_args()
phys = meshio.read(args.phys)
weight = meshio.read(args.weight)
# Taken node by node, so both solves must have produced the same node list.
# If they did not, every value below is meaningless and nothing else checks.
if phys.points.shape != weight.points.shape:
sys.exit(
"Node counts differ: %s has %d nodes, %s has %d. Both solves must "
"read the same mesh (same wires2d/ directory)."
% (args.phys, len(phys.points), args.weight, len(weight.points))
)
if not np.allclose(phys.points, weight.points, rtol=args.rtol, atol=args.atol):
worst = np.max(np.linalg.norm(phys.points - weight.points, axis=1))
sys.exit(
"Node positions do not match (largest discrepancy %.3e m). The two "
"solves were run on different meshes." % worst
)
E = as_vectors(find_array(phys.point_data, args.field, args.phys), args.phys)
Ew = as_vectors(find_array(weight.point_data, args.field, args.weight), args.weight)
# A zero field means the solve never ran: Laplace with no Dirichlet
# condition applied has the trivial solution and Elmer reports no error.
# Without this the chain completes and writes zeros, and the only symptom
# is a blank plot.
for label, arr, path in (
("physical", E, args.phys),
("weighting", Ew, args.weight),
):
if not np.any(arr):
sys.exit(
"the %s field in %s is identically zero.\n"
"Elmer returned the trivial solution, which means no boundary "
"condition was applied. Compare the Target Bodies and Target "
"Boundaries numbers in the .sif against wires2d/mesh.names -- "
"ElmerGrid's -autoclean renumbers them." % (label, path)
)
# Elmer may pad 2D vectors to three components; compare only the
# components both arrays actually carry.
ncomp = min(E.shape[1], Ew.shape[1])
if E.shape[1] != Ew.shape[1]:
print("note: component counts differ (%d vs %d), using the first %d"
% (E.shape[1], Ew.shape[1], ncomp))
dot = np.einsum("ij,ij->i", E[:, :ncomp], Ew[:, :ncomp])
out = meshio.Mesh(
points=phys.points,
cells=phys.cells,
point_data=dict(phys.point_data),
cell_data=dict(phys.cell_data),
)
out.point_data["DotProduct"] = dot
out.point_data["WeightingField"] = Ew
if args.scale is not None:
out.point_data["ScaledDotProduct"] = args.scale * dot
meshio.write(args.out, out)
finite = dot[np.isfinite(dot)]
print("nodes : %d" % len(dot))
print("components used : %d" % ncomp)
print("DotProduct min : %.6e V/m^2" % finite.min())
print("DotProduct max : %.6e V/m^2" % finite.max())
print("DotProduct mean : %.6e V/m^2" % finite.mean())
if len(finite) != len(dot):
print("WARNING: %d non-finite nodes" % (len(dot) - len(finite)))
print("wrote %s" % args.out)
if __name__ == "__main__":
main()

107
anasen_fem/garfield_sim.py Normal file
View File

@ -0,0 +1,107 @@
import ROOT
import os
import sys
# 1. FIX: Manually load the Garfield library if it's not in the ROOT namespace
# Update this path to your actual installation location
garfield_lib_path = "/home/vs19g/garfieldpp/install/lib/libGarfield.so" #penguin path
# garfield_lib_path = "/home/vsitaraman/garfieldpp/install/lib/libGarfield.so" #laptop path
if os.path.exists(garfield_lib_path):
ROOT.gSystem.Load(garfield_lib_path)
else:
print(f"CRITICAL ERROR: {garfield_lib_path} not found.")
sys.exit(1)
# Verify access
try:
test_gas = ROOT.Garfield.MediumMagboltz()
except AttributeError:
print("ERROR: Garfield shared library loaded, but 'Garfield' namespace not found.")
sys.exit(1)
# --- 2. GAS SETUP (96% He, 4% CO2) ---
gas = ROOT.Garfield.MediumMagboltz()
gas_file = "He96_CO2_4_260Torr.gas"
if not os.path.exists(gas_file):
print("Generating new Magboltz gas table (260 Torr)...")
# --- Optimized Magboltz Settings ---
gas.SetComposition("he", 96.0, "co2", 4.0)
gas.SetTemperature(293.15)
gas.SetPressure(260.0)
# 1. Limit the Field Grid:
gas.SetFieldGrid(10., 80000., 20, True)
# 2. Reduce the precision slightly for the first run:
gas.GenerateGasTable(8)
gas.WriteGasFile(gas_file)
else:
print(f"Loading existing gas table: {gas_file}")
gas.LoadGasFile(gas_file)
# --- 3. FIELD MAP SETUP ---
fm = ROOT.Garfield.ComponentElmer2d()
fm.Initialise("wires2d/mesh.header",
"wires2d/mesh.elements",
"wires2d/mesh.nodes",
"dielectrics.dat",
"wires2d/elstatics.result",
"mm")
# Set the medium (Body 13 from your Gmsh script)
fm.SetMedium(0, gas)
# --- 4. SENSOR AND DRIFT SETUP ---
sensor = ROOT.Garfield.Sensor()
sensor.AddComponent(fm)
sensor.SetArea(-50.0, -50.0, -5.0, 50.0, 50.0, 5.0) #hardcoding the sesnsor area to define a psuedo 3d geometry
# Heavy Ion Drift (RKF) - Best for the general track
drift = ROOT.Garfield.DriftLineRKF()
drift.SetSensor(sensor)
# Electron Avalanche (Microscopic) - Best for high-field gain
aval = ROOT.Garfield.AvalancheMicroscopic()
aval.SetSensor(sensor)
# --- 5. EXECUTION ---
# Starting position (e.g., near the IC wires at r=23mm or closer to Anodes)
x0, y0, z0, t0 = 3.50, 0.0, 0.0, 0.0
print(f"Simulating heavy ion drift from r={x0}...")
drift.DriftIon(x0, y0, z0, t0)
# Create a file to store the heavy ion track
with open("heavy_ion_track.csv", "w") as f:
f.write("x,y,z,t\n")
# After running drift.DriftIon(x0, y0, z0, t0):
n_points = drift.GetNumberOfDriftLinePoints()
for i in range(n_points):
xi, yi, zi, ti = ROOT.double(0), ROOT.double(0), ROOT.double(0), ROOT.double(0)
drift.GetDriftLinePoint(i, xi, yi, zi, ti)
f.write(f"{xi},{yi},{zi},{ti}\n")
print(f"Simulating electron avalanche from r={x0}...")
# AvalancheElectron(x, y, z, t, energy, dx, dy, dz)
aval.AvalancheElectron(x0, y0, z0, t0, 0.1, 0.0, 0.0, 0.0)
with open("avalanche_endpoints.csv", "w") as f:
f.write("x,y,z,t\n")
# After aval.AvalancheElectron(...)
n_endpoints = aval.GetNumberOfEndpoints()
for i in range(n_endpoints):
# Get start and end points of each electron in the avalanche
x1, y1, z1, t1, e1 = ROOT.double(0), ROOT.double(0), ROOT.double(0), ROOT.double(0), ROOT.double(0)
x2, y2, z2, t2, e2, status = ROOT.double(0), ROOT.double(0), ROOT.double(0), ROOT.double(0), ROOT.double(0), ROOT.int(0)
aval.GetEndpoint(i, x1, y1, z1, t1, e1, x2, y2, z2, t2, e2, status)
# We save the endpoint (x2, y2, z2) where the electron was collected or attached
f.write(f"{x2},{y2},{z2},{t2}\n")
print("Simulation complete.")

114
anasen_fem/junk/wires.py Executable file
View File

@ -0,0 +1,114 @@
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
acolors = plt.get_cmap('tab20',24)
ccolors = plt.get_cmap('tab20',24)
k=-2*np.pi/24.
offset = 6*k + 3*k #-pi/2
xarra_1 = np.array([37*np.cos(k*i+offset) for i in np.arange(0,24)])
yarra_1 = np.array([37*np.sin(k*i+offset) for i in np.arange(0,24)])
labelsa_1 = np.array([i for i in np.arange(0,24)])
fig,ax = plt.subplots(figsize=(10,10))
ax.invert_yaxis()
ax.plot(xarra_1,yarra_1,"x",label="anode, z=-L/2")
for x,y,label in zip(xarra_1,yarra_1,labelsa_1):
ax.text(x,y,label)
kc=2*np.pi/24.
offsetc = -4*kc + 2*kc - np.pi/24 #-pi/4
xarrc_1 = np.array([42*np.cos(kc*i+offsetc) for i in np.arange(0,24)])
yarrc_1 = np.array([42*np.sin(kc*i+offsetc) for i in np.arange(0,24)])
labelsc_1 = np.array([i for i in np.arange(0,24)])
ax.plot(xarrc_1,yarrc_1,"o",label="cathode, z=-L/2, where they are picked up")
for x,y,label in zip(xarrc_1,yarrc_1,labelsc_1):
ax.text(x,y,label)
plt.title("z=-L/2 plane, beam going into the plane along +z, (+x right, +y down)")
plt.grid()
plt.legend()
plt.savefig("plane1.png")
plt.show()
fig,ax = plt.subplots(figsize=(10,10))
ax.invert_yaxis()
offset = offset-3*k
xarra_2 = np.array([37*np.cos(k*i+offset) for i in np.arange(0,24)])
yarra_2 = np.array([37*np.sin(k*i+offset) for i in np.arange(0,24)])
labelsa_2 = np.array([i for i in np.arange(0,24)])
ax.plot(xarra_2,yarra_2,"x",label="anode, z=+L/2, where they are picked up")
for x,y,label in zip(xarra_2,yarra_2,labelsa_2):
ax.text(x,y,label)
offsetc = offsetc-3*kc
xarrc_2 = np.array([42*np.cos(kc*i+offsetc) for i in np.arange(0,24)])
yarrc_2 = np.array([42*np.sin(kc*i+offsetc) for i in np.arange(0,24)])
labelsc_2 = np.array([i for i in np.arange(0,24)])
ax.plot(xarrc_2,yarrc_2,"o",label="cathode, z=+L/2")
for x,y,label in zip(xarrc_2,yarrc_2,labelsc_2):
ax.text(x,y,label)
plt.title("z=+L/2 plane, beam going into the plane along +z, (+x right, +y down)")
plt.grid()
plt.legend()
plt.savefig("plane2.png")
plt.show()
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111,projection='3d')
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
xx_a = np.array([[x1,x2] for x1,x2 in zip(xarra_1,xarra_2)])
yy_a = np.array([[y1,y2] for y1,y2 in zip(yarra_1,yarra_2)])
zz_a = np.array([[-173.5,173.5] for x1,x2 in zip(xarra_1,xarra_2)])
for i,[xx,yy,zz] in enumerate(zip(xx_a,yy_a,zz_a)):
ax.plot(xx,yy,zz,'-',color=acolors(i/24))
for i,[x,y,label] in enumerate(zip(xarra_1,yarra_1,labelsa_1)):
ax.text(x,y,-173,"a"+str(label),color=acolors(i/24))
for i,[x,y,label] in enumerate(zip(xarra_2,yarra_2,labelsa_2)):
ax.text(x,y,+173,"a"+str(label),color=acolors(i/24))
xx_c = np.array([[x1,x2] for x1,x2 in zip(xarrc_1,xarrc_2)])
yy_c = np.array([[y1,y2] for y1,y2 in zip(yarrc_1,yarrc_2)])
zz_c = np.array([[-173.5,173.5] for x1,x2 in zip(xarrc_1,xarrc_2)])
for i,[xx,yy,zz] in enumerate(zip(xx_c,yy_c,zz_c)):
ax.plot(xx,yy,zz,'--',color=ccolors(((47-i)%24)/24))
for i,[x,y,label] in enumerate(zip(xarrc_1,yarrc_1,labelsc_1)):
ax.text(x,y,-173,"c"+str(label),color=ccolors(((25-i)%24)/24))
for i,[x,y,label] in enumerate(zip(xarrc_2,yarrc_2,labelsc_2)):
ax.text(x,y,+173,"c"+str(label),color=ccolors(((47-i)%24)/24))
ax.view_init(elev=-53, azim=-106, roll=18)
plt.tight_layout()
plt.show()
phi_qqq = np.array([[2*np.pi*(-i*16+j+0.5)/(16*4) for i in range(4)] for j in range(16)])
print(phi_qqq)
#'''
for i,[phi1,phi2,phi3,phi4] in enumerate(phi_qqq):
ax.plot([50*np.cos(phi1),100*np.cos(phi1)],[50*np.sin(phi1),100*np.sin(phi1)],[100,100],'-',color='red')
ax.text(104*np.cos(phi1),104*np.sin(phi1),100,"0_%d"%(i),color="red")
ax.plot([50*np.cos(phi2),100*np.cos(phi2)],[50*np.sin(phi2),100*np.sin(phi2)],[100,100],'-',color='green')
ax.text(104*np.cos(phi2),104*np.sin(phi2),100,"1_%d"%(i),color="green")
ax.plot([50*np.cos(phi3),100*np.cos(phi3)],[50*np.sin(phi3),100*np.sin(phi3)],[100,100],'-',color='blue')
ax.text(104*np.cos(phi3),104*np.sin(phi3),100,"2_%d"%(i),color="blue")
ax.plot([50*np.cos(phi4),100*np.cos(phi4)],[50*np.sin(phi4),100*np.sin(phi4)],[100,100],'-',color='brown')
ax.text(104*np.cos(phi4),104*np.sin(phi4),100,"3_%d"%(i),color="brown")
#'''
#coords_qqq = np.array([[50*np.cos(phi),100*np.sin(phi),100] for phi in phi_qqq]).T
plt.tight_layout()
plt.show()

View File

@ -0,0 +1,71 @@
Check Keywords Warn
Header
Mesh DB "." "wires2d"
End
Simulation
Coordinate System = Cartesian 2D
Simulation Type = Steady State
Steady State Max Iterations = 1
Output File = "elstatics.result"
Post File = "elstatics.ep"
End
Constants
Permittivity Of Vacuum = 8.8542e-12
End
Body 1
Target Bodies(1) = 13
Equation = 1
Material = 1
End
Equation 1
Active Solvers(2) = 1 2
End
Material 1
Relative Permittivity = 1
End
Solver 1
Equation = Electrostatics
Procedure = "StatElecSolve" "StatElecSolver"
Variable = Potential
Variable DOFs = 1
Calculate Electric Field = True
Calculate Electric Flux = False
Linear System Solver = Iterative
Linear System Iterative Method = CG
Linear System Max Iterations = 500
Linear System Convergence Tolerance = 1.0e-8
Linear System Preconditioning = ILU1
End
Solver 2
Equation = Electric Force
Procedure = "ElectricForce" "StatElecForce"
End
Boundary Condition 1
Target Boundaries = 10
Potential = 650
Calculate Electric Force = True
End
Boundary Condition 2
Target Boundaries = 20
Potential = 0
End

91
anasen_fem/junk/wires_gmsh.py Executable file
View File

@ -0,0 +1,91 @@
import numpy as np
import gmsh
gmsh.initialize()
gmsh.model.add("adaptive_mesh")
gmsh.option.setNumber('General.NumThreads', 4)
#gmsh.option.setNumber("Mesh.Adapt.MaxNumberOfElements", 200000)
#gmsh.option.setNumber("Mesh.Adapt.MaxNumberOfNodes", 200000)
#gmsh.option.setNumber("Mesh.Adapt.MaxIter",5)
#gmsh.option.setNumber("Mesh.MeshSizeMin", 5e-3)
#gmsh.option.setNumber("Mesh.MeshSizeMax", 10.0)
#gmsh.option.setNumber("Mesh.CharacteristicLengthFromCurvature", 0)
lc = 0.01
#anodes, plane 1 at -zmax/2
k=-2*np.pi/24.
offset = 6*k + 3*k #-pi/2
xarra_1 = np.array([37*np.cos(k*i+offset) for i in np.arange(0,24)])
yarra_1 = np.array([37*np.sin(k*i+offset) for i in np.arange(0,24)])
#cathodes, plane 1 at -zmax/2
kc=2*np.pi/24.
offsetc = -4*kc + 2*kc - np.pi/24 #-pi/4
xarrc_1 = np.array([42*np.cos(kc*i+offsetc) for i in np.arange(0,24)])
yarrc_1 = np.array([42*np.sin(kc*i+offsetc) for i in np.arange(0,24)])
#anodes, plane 2 at +zmax/2
offset = offset-3*k
xarra_2 = np.array([37*np.cos(k*i+offset) for i in np.arange(0,24)])
yarra_2 = np.array([37*np.sin(k*i+offset) for i in np.arange(0,24)])
#cathodes, plane2 at +zmax/2
offsetc = offsetc-3*kc
xarrc_2 = np.array([42*np.cos(kc*i+offsetc) for i in np.arange(0,24)])
yarrc_2 = np.array([42*np.sin(kc*i+offsetc) for i in np.arange(0,24)])
pa1 = []
pa2 = []
pc1 = []
pc2 = []
wire_radius = 0.254 #mm
anode_wires = []
cathode_wires = []
aw_tags = [(3,i) for i in range(24)]
cw_tags = [(3,i+24) for i in range(24)]
for i,[xa,ya,xc,yc,xa2,ya2,xc2,yc2] in enumerate(zip(xarra_1,yarra_1,xarrc_1,yarrc_1,xarra_2,yarra_2,xarrc_2,yarrc_2)):
print(i,xa,ya,-178.3,xc,yc,-178.3,xa2,ya2,178.3,xc2,yc2,178.3)
anode_wires.append(gmsh.model.occ.addCylinder(xa,ya,-178.3,(xa2-xa),(ya2-ya),178.3*2,wire_radius,i)) #x,y,z of first face center, dx,dy,dz of the axis, then the wire radius
cathode_wires.append(gmsh.model.occ.addCylinder(xc,yc,-178.3,(xc2-xc),(yc2-yc),178.3*2,wire_radius,i+24)) #cathode tags 24-47, anode 0-23
anasen_barrel = gmsh.model.occ.addCylinder(0,0,-500,0,0,500+605,300,1234) #tag 1234
#anasen_barrel = gmsh.model.occ.addCylinder(0,0,-500,0,0,500+605,300,1234) #tag 1234
gmsh.model.occ.synchronize()
all_wires = aw_tags+cw_tags
gmsh.model.occ.fragment([(3,1234)],all_wires)
gmsh.model.occ.removeAllDuplicates()
gmsh.model.occ.synchronize()
gmsh.option.setNumber("Geometry.Tolerance", 1e-6)
gmsh.option.setNumber("Geometry.OCCFixDegenerated", 1)
gmsh.option.setNumber("Geometry.OCCFixSmallEdges", 1)
gmsh.option.setNumber("Geometry.OCCFixSmallFaces", 1)
wire_surfs = []
for w in anode_wires + cathode_wires:
wire_surfs += [s[1] for s in gmsh.model.getBoundary([(3,w)], oriented=False) if s[0] == 2]
#'''
f1 = gmsh.model.mesh.field.add("Distance")
gmsh.model.mesh.field.setNumbers(f1, "FacesList", wire_surfs) # Example curves
f2 = gmsh.model.mesh.field.add("Threshold")
gmsh.model.mesh.field.setNumber(f2, "InField", f1)
gmsh.model.mesh.field.setNumber(f2, "SizeMin", 0.05)
gmsh.model.mesh.field.setNumber(f2, "SizeMax", 5.)
gmsh.model.mesh.field.setNumber(f2, "DistMin", 1.)
gmsh.model.mesh.field.setNumber(f2, "DistMax", 20.)
gmsh.model.mesh.field.setAsBackgroundMesh(f2)
#'''
gmsh.option.setNumber("Mesh.Algorithm", 2)
gmsh.option.setNumber("Mesh.Algorithm3D", 1) # For 3D meshes
gmsh.model.mesh.generate(dim=3)
#gmsh.model.mesh.refine()
#gmsh.model.mesh.refine()
#gmsh.model.mesh.refine()
gmsh.fltk.run()
gmsh.finalize()

View File

@ -0,0 +1,87 @@
import numpy as np
import gmsh
gmsh.initialize()
#gmsh.model.add("adaptive_mesh")
gmsh.option.setNumber('General.NumThreads', 4)
#gmsh.option.setNumber("Mesh.Adapt.MaxNumberOfElements", 200000)
#gmsh.option.setNumber("Mesh.Adapt.MaxNumberOfNodes", 200000)
#gmsh.option.setNumber("Mesh.Adapt.MaxIter",5)
#gmsh.option.setNumber("Mesh.MeshSizeMin", 5e-3)
#gmsh.option.setNumber("Mesh.MeshSizeMax", 10.0)
gmsh.option.setNumber("Geometry.Tolerance", 1e-2)
#gmsh.option.setNumber("Mesh.CharacteristicLengthFromCurvature", 0)
lc = 0.04
#anodes, plane 1 at -zmax/2
k=-2*np.pi/24.
offset = 6*k + 3*k #-pi/2
xarra_1 = np.array([37*np.cos(k*i+offset) for i in np.arange(0,24)])
yarra_1 = np.array([37*np.sin(k*i+offset) for i in np.arange(0,24)])
#cathodes, plane 1 at -zmax/2
kc=2*np.pi/24.
offsetc = -4*kc + 2*kc - np.pi/24 #-pi/4
xarrc_1 = np.array([42*np.cos(kc*i+offsetc) for i in np.arange(0,24)])
yarrc_1 = np.array([42*np.sin(kc*i+offsetc) for i in np.arange(0,24)])
#anodes, plane 2 at +zmax/2
offset = offset-3*k
xarra_2 = np.array([37*np.cos(k*i+offset) for i in np.arange(0,24)])
yarra_2 = np.array([37*np.sin(k*i+offset) for i in np.arange(0,24)])
#cathodes, plane2 at +zmax/2
offsetc = offsetc-3*kc
xarrc_2 = np.array([42*np.cos(kc*i+offsetc) for i in np.arange(0,24)])
yarrc_2 = np.array([42*np.sin(kc*i+offsetc) for i in np.arange(0,24)])
wire_radius = 0.254 #mm
anode_wires = []
cathode_wires = []
aw_tags = [(3,i) for i in range(24)]
cw_tags = [(3,i+24) for i in range(24)]
for i,[xa,ya,xc,yc,xa2,ya2,xc2,yc2] in enumerate(zip(xarra_1,yarra_1,xarrc_1,yarrc_1,xarra_2,yarra_2,xarrc_2,yarrc_2)):
print(i,xa,ya,-178.3,xc,yc,-178.3,xa2,ya2,178.3,xc2,yc2,178.3)
pa1 = gmsh.model.occ.addPoint(xa,ya,-178.3,lc)
pa2 = gmsh.model.occ.addPoint(xa2,ya2,178.3,lc)
pc1 = gmsh.model.occ.addPoint(xc,yc,-178.3,lc)
pc2 = gmsh.model.occ.addPoint(xc2,yc2,178.3,lc)
linea = gmsh.model.occ.addLine(pa1,pa2)
linec = gmsh.model.occ.addLine(pc1,pc2)
anode_wires.append(linea)
cathode_wires.append(linec)
#anasen_barrel = gmsh.model.occ.addCylinder(0,0,-500,0,0,500+605,300,1234) #tag 1234
anasen_barrel = gmsh.model.occ.addCylinder(0,0,-200, 0,0,400, 300) #tag 1234
gmsh.model.occ.synchronize()
gmsh.model.mesh.embed(1,anode_wires+cathode_wires,3,anasen_barrel)
f1 = gmsh.model.mesh.field.add("Distance")
gmsh.model.mesh.field.setNumbers(f1,"CurvesList",anode_wires+cathode_wires)
f2 = gmsh.model.mesh.field.add("Threshold")
gmsh.model.mesh.field.setNumber(f2,"InField",f1)
gmsh.model.mesh.field.setNumber(f2,"SizeMin",0.08)
gmsh.model.mesh.field.setNumber(f2,"SizeMax",5)
gmsh.model.mesh.field.setNumber(f2,"DistMin",1)
gmsh.model.mesh.field.setNumber(f2,"DistMax",20)
gmsh.model.mesh.field.setAsBackgroundMesh(f2)
gmsh.model.addPhysicalGroup(1, anode_wires, tag=10)
gmsh.model.setPhysicalName(1,10,"anode_wires")
gmsh.model.addPhysicalGroup(1, cathode_wires, tag=20)
gmsh.model.setPhysicalName(1,20,"cathode_wires")
gmsh.option.setNumber("Mesh.Algorithm",6)
gmsh.option.setNumber("Mesh.Algorithm3D", 10) # For 3D meshes
gmsh.model.mesh.generate(dim=3)
gmsh.model.mesh.refine()
#gmsh.model.mesh.refine()
#gmsh.model.mesh.refine()
gmsh.fltk.run()
gmsh.finalize()

279
anasen_fem/paraview_dotproduct.py Executable file
View File

@ -0,0 +1,279 @@
#!/home/vsitaraman/ParaView-6.1.0-RC1-MPI-Linux-Python3.12-x86_64/bin/pvbatch
# Point the shebang above at your own pvbatch/pvpython, as for paraview_plotter.py.
#
# Renders the E . E_w map written by dotproduct.py.
#
# By Shockley-Ramo the dot product describes the current induced on ONE
# electrode: the cathode that wires2d_weight.sif held at 1 V. Everywhere else
# the number is just the tail of that electrode's weighting field, so the view
# is centred on that wire and nothing else. Its position is read out of the
# weighting solve rather than recomputed from the geometry -- the driven
# electrode is wherever the weighting potential reaches 1.
#
# Usage (from anasen_fem/):
# ./paraview_dotproduct.py [dotproduct.vtu] [output.png] [weight.vtu]
#
# Re-plotting an archived z needs its archived weighting solve as well, since
# that is where the driven cathode's position is read from:
# ./paraview_dotproduct.py wires2d/vtu_files/dotproduct_10_0.0000.vtu \
# png/DotProduct_output_z_10_0.0000.png \
# wires2d/vtu_files/elfield_weight_10_0.0000.vtu
import sys
import numpy as np
from paraview.simple import *
INPUT_VTU = sys.argv[1] if len(sys.argv) > 1 else "wires2d/dotproduct.vtu"
OUTPUT_IMAGE = sys.argv[2] if len(sys.argv) > 2 else "DotProduct_output.png"
# Weighting solve, used only to locate the driven cathode. Must be the one that
# belongs to this dot product -- the wire moves with z.
WEIGHT_VTU = sys.argv[3] if len(sys.argv) > 3 else "wires2d/elfield_weight_t0001.vtu"
# Half-height of the view in metres. Cathodes sit every 15 degrees at a radius
# of about 36.4 mm, so the neighbours either side are 9.5 mm away; 14 mm takes
# them both in with a margin.
# Image size. The structure round the driven cathode is much wider than it is
# tall, so a square frame spends most of its area on empty gas.
VIEW_SIZE = [2000, 1200]
# CameraParallelScale, which is the half-HEIGHT of the view in metres. The
# width follows from the aspect: half-height * (VIEW_SIZE[0] / VIEW_SIZE[1]).
# So widening the frame alone does not crop anything, it just shows more
# sideways; the scale has to come down with it. 0.0084 at 2000x1200 keeps the
# same 28 mm width as the old square 0.014 and trims the height to 16.8 mm.
ZOOM_SCALE = 0.0084
# The driven cathode swings round the axis as z changes, so with a fixed "up"
# every z comes out rotated by a different amount and the shots cannot be laid
# side by side. Aligning up with the outward radial direction through the
# cathode puts the detector axis below and the barrel wall above in every
# frame, whatever z. Set False for plain screen-aligned axes.
ALIGN_RADIAL = True
# Shift of the view centre along the outward radial, in metres. Up in the frame
# is the outward radial, so a NEGATIVE value walks the camera in towards the
# detector axis and the cathode rides higher in the picture. Positive drops it.
# Purely framing; it does not move the wire.
CENTER_SHIFT = -0.0036
# Second, wider shot over the same quadrant paraview_plotter.py frames, so the
# dot product can be laid beside the field and contour views of that z. Centre
# is at x < 0, y > 0; negate the y for the lower-left quadrant instead.
# Colour range for DotProduct. Both ends negative: E and E_w point in broadly
# opposite senses over most of the drift volume.
# Most of the painted patch lies between -2e7 and -2e6. Against a range
# reaching -3.1e8 that is the top few percent of the scale, so it all came out
# at the white end of Greens. Narrowing the range spreads those values over the
# green; anything stronger simply clamps to the darkest end, which only affects
# the last fraction of a millimetre at the wire surface.
DOT_MIN, DOT_MAX = -8.0e7, -3.0e6
# Opacity of the painted map. Anything at least as strong as OPAQUE_BELOW is
# drawn solid; from there it ramps down to transparent at FADE_TO, so the grey
# shows through with a soft round edge rather than the ragged one a hard cut
# leaves.
#
# The plateau matters more than either endpoint. Ramping all the way from
# DOT_MIN (-3.1e8) meant the opacity at -5e7 was only about 0.13, so the whole
# patch read as washed out however the fade point was set.
OPAQUE_BELOW = -2.0e7
FADE_TO = -2.0e6
# Coarse cut, only to keep the far field out of the render. Must be nearer zero
# than FADE_TO so its hard edge lands where the surface is already fully
# transparent and cannot be seen.
PAINT_CUT = -5.0e5
# "signed-log" maps sign and magnitude together through a signed logarithm and
# a diverging colour map; "linear" is the earlier one-sided Greens scale, which
# the constants above still drive.
COLOR_MODE = "signed-log"
# X0 sets where the mapping turns from linear to logarithmic, and so how much
# of the weak far field survives at all: at 1e6 the data map to -2.51 .. 1.62,
# against -3.51 .. 2.61 at 1e5. Raise it to paint less.
SYMLOG_X0 = 1.0e6
SYMLOG_LIMIT = 2.5 # symmetric colour limit; match it to the mapped range
SYMLOG_OPAQUE = 0.6 # |value| at which the map is fully opaque
SYMLOG_FADE = 0.3 # |value| below which it is transparent
# Shape of the two opacity ramps, as opposed to where they sit.
#
# A piecewise function's midpoint describes the segment running RIGHTWARD from
# each node, and the two ramps run in opposite senses -- falling on the
# negative side, rising on the positive. So a single midpoint below 0.5 applied
# to both makes the negative lobe fade out sooner while the positive lobe goes
# opaque sooner, rendering the two polarities at different effective
# thresholds. Mirroring it keeps them symmetric: below 0.5 both sides go opaque
# sooner, so more is painted, equally on each.
#
# Sharpness is the independent dial for how abrupt the edge is: 0 smooth, 1 a
# hard step. 0.5 is already close to a step.
SYMLOG_MIDPOINT = 0.3
SYMLOG_SHARPNESS = 0.0
DIVERGING_PRESET = "PRGn" # purple / white / green; zero sits at white
BACKGROUND = [0.35, 0.34, 0.33] # grey
# Equipotential lines over the whole frame, painted gas or not. Off by default:
# the map is the subject here, and the lines are already in the contour plots.
SHOW_CONTOURS = False
CONTOUR_BY = "potential"
CONTOUR_LEVELS = list(np.arange(0, 660, 660 / 40.0))
def threshold_between(source, array, low, high):
"""Threshold filter, tolerating the pre-5.10 property names."""
t = Threshold(Input=source, Scalars=["POINTS", array])
try:
t.LowerThreshold = low
t.UpperThreshold = high
t.ThresholdMethod = "Between"
except Exception:
t.ThresholdRange = [low, high]
return t
# --- locate the driven cathode: the weighting potential is 1 on it ---
weight_reader = XMLUnstructuredGridReader(FileName=[WEIGHT_VTU])
driven = threshold_between(weight_reader, "potential", 0.99, 1.01)
driven.UpdatePipeline()
info = driven.GetDataInformation()
if info.GetNumberOfPoints() == 0:
sys.exit(
"no nodes with weighting potential ~1 in %s -- the weighting solve did\n"
"not drive any electrode, so there is nothing to centre on." % WEIGHT_VTU
)
b = info.GetBounds()
CATHODE = [0.5 * (b[0] + b[1]), 0.5 * (b[2] + b[3]), 0.0]
print("driven cathode at x = %.5f m, y = %.5f m" % (CATHODE[0], CATHODE[1]))
radius = (CATHODE[0] ** 2 + CATHODE[1] ** 2) ** 0.5
outward = [CATHODE[0] / radius, CATHODE[1] / radius, 0.0] if radius > 0 else [0.0, 1.0, 0.0]
# Frame centre, offset from the wire along that radial.
CENTER = [
CATHODE[0] + CENTER_SHIFT * outward[0],
CATHODE[1] + CENTER_SHIFT * outward[1],
0.0,
]
Delete(driven)
Delete(weight_reader)
# --- the dot product map ---
reader = XMLUnstructuredGridReader(FileName=[INPUT_VTU])
renderView = GetActiveViewOrCreate("RenderView")
renderView.ViewSize = VIEW_SIZE
renderView.OrientationAxesVisibility = 1
renderView.UseColorPaletteForBackground = 0
renderView.Background = BACKGROUND
renderView.MultiSamples = 8
if COLOR_MODE == "signed-log":
# E . E_w spans about 3.5 decades negative and 2.6 positive, and 38% of the
# nodes are positive -- charge drifting there induces current of the
# opposite polarity on the cathode. A linear scale over one sign shows
# neither the decades nor the sign, so map through a signed log:
#
# sign(d) * log10(1 + |d| / SYMLOG_X0)
#
# sign() is not in the calculator namespace, hence d/(|d|+1); the +1 is
# negligible beside the 1e5 scale and the expression tends to 0 anyway
# where d does.
calc = PythonCalculator(Input=reader)
calc.ArrayName = "SignedLogDot"
calc.ArrayAssociation = "Point Data"
calc.Expression = (
"(DotProduct/(abs(DotProduct)+1.0))*log10(1.0+abs(DotProduct)/%g)"
% SYMLOG_X0
)
painted = calc
array = "SignedLogDot"
colour_range = (-SYMLOG_LIMIT, SYMLOG_LIMIT) # symmetric, so zero is neutral
preset = DIVERGING_PRESET
# Transparent either side of zero, opaque past SYMLOG_OPAQUE, both signs.
_m, _s = SYMLOG_MIDPOINT, SYMLOG_SHARPNESS
opacity_points = [
-SYMLOG_LIMIT, 1.0, 0.5, _s,
-SYMLOG_OPAQUE, 1.0, 1.0 - _m, _s, # mirrored: this ramp falls
-SYMLOG_FADE, 0.0, 0.5, _s,
SYMLOG_FADE, 0.0, _m, _s, # this one rises
SYMLOG_OPAQUE, 1.0, 0.5, _s,
SYMLOG_LIMIT, 1.0, 0.5, _s,
]
bar_title = "sign(E.Ew) log10(1+|E.Ew|/%g)" % SYMLOG_X0
else:
painted = threshold_between(reader, "DotProduct", -1.0e30, PAINT_CUT)
array = "DotProduct"
colour_range = (DOT_MIN, DOT_MAX)
preset = "Greens"
opacity_points = [
DOT_MIN, 1.0, 0.5, 0.0,
OPAQUE_BELOW, 1.0, 0.5, 0.0,
FADE_TO, 0.0, 0.5, 0.0,
]
bar_title = "E . E_w (V/m^2)"
surface_display = Show(painted, renderView)
surface_display.Representation = "Surface"
ColorBy(surface_display, ("POINTS", array))
dotLUT = GetColorTransferFunction(array)
dotLUT.ApplyPreset(preset, True)
dotLUT.RescaleTransferFunction(colour_range[0], colour_range[1])
# Points go (value, opacity, midpoint, sharpness) in ascending value.
dotPWF = GetOpacityTransferFunction(array)
dotPWF.Points = opacity_points
dotLUT.ScalarOpacityFunction = dotPWF
dotLUT.EnableOpacityMapping = 1
surface_display.SetScalarBarVisibility(renderView, True)
try:
GetScalarBar(dotLUT, renderView).Title = bar_title
except Exception as exc:
print("note: could not set the scalar bar title (%s)" % exc)
# --- contour lines over the whole field, including the unpainted gas ---
if SHOW_CONTOURS:
contour_filter = Contour(Input=reader, ContourBy=["POINTS", CONTOUR_BY])
contour_filter.Isosurfaces = CONTOUR_LEVELS
contour_display = Show(contour_filter, renderView)
contour_display.LineWidth = 1.0
contour_display.DiffuseColor = [1.0, 1.0, 1.0]
# ColorBy(rep, None) is rejected by ParaView 6.1 -- it forwards the
# association as the string 'NONE' and raises -- so set the property.
contour_display.ColorArrayName = [None, ""]
contour_display.SetScalarBarVisibility(renderView, False)
# --- camera: parallel projection, centred on the driven cathode ---
# ParaView resets the camera on a view's FIRST render, throwing away anything
# set beforehand, so burn that render here and set the camera after it.
# Measured: scale 0.008 set before the first Render comes back as 0.021; set
# again afterwards it holds.
Render()
view = GetActiveView()
view.CameraParallelScale = ZOOM_SCALE
view.CenterOfRotation = CENTER
view.CameraPosition = [CENTER[0], CENTER[1], 1.0]
view.CameraFocalPoint = CENTER
if ALIGN_RADIAL:
up = outward
print("view rotated %.1f deg so the outward radial is up"
% np.degrees(np.arctan2(up[0], up[1])))
else:
up = [0.0, 1.0, 0.0]
view.CameraViewUp = up
view.CameraParallelProjection = 1
Render()
SaveScreenshot(OUTPUT_IMAGE)
print("Saved %s" % OUTPUT_IMAGE)

268
anasen_fem/paraview_plotter.py Executable file
View File

@ -0,0 +1,268 @@
#!/home/vsitaraman/ParaView-6.1.0-RC1-MPI-Linux-Python3.12-x86_64/bin/pvbatch
# #######!/home/vsitaraman/ParaView-6.1.0-MPI-Linux-Python3.12-x86_64/bin/pvbatch
import numpy as np
import sys
from paraview.simple import *
# Optional argument so an archived VTU can be re-plotted without re-solving:
# ./paraview_plotter.py wires2d/vtu_files/elfield_anasen_10_0.0000.vtu
INPUT_VTU = sys.argv[1] if len(sys.argv) > 1 else "wires2d/elfield_anasen_t0001.vtu"
# --- contour settings ---
# The whole-PC view keeps the original sparse, evenly spaced levels; at that
# scale more lines just fill in solid. The quadrant gets the denser, biased
# set, since that is where the structure between wires is actually readable.
POT_MIN, POT_MAX = 0.0, 660.0
N_CONTOURS_FULL, CONTOUR_BIAS_FULL = 40, 1.0
N_CONTOURS_QUARTER, CONTOUR_BIAS_QUARTER = 80, 1.0
# Line widths. Thin lines wash out their own colour, so the quadrant views draw
# heavier than the full-PC one; tubes keep them smooth at 2000 px.
LINE_WIDTH_FULL = 3.0
LINE_WIDTH_QUARTER = 2.5
STREAM_LINE_WIDTH = 2.5
# Arrows are glyphed onto the contour points, so doubling the quadrant contour
# density doubled the arrow count too. This offsets that.
GLYPH_STRIDE = 96
# --- quadrant view ---
# Centre sits at radius 35.4 mm, near the outer edge of the wire band, which
# pushes the wires to one side and leaves the far corner empty. Pulled in to
# 31.8 mm so the band sits more centrally.
ZOOM_CENTER = [-0.0225, 0.0225, 0.0]
ZOOM_SCALE = 0.022 # half-height of the view in metres; larger = more in frame
def contour_levels(n, bias):
"""Isosurface values.
phi ~ ln(r) around a wire, so evenly spaced levels crowd onto the wire
surfaces and thin out in the gas. Raising a symmetric parameter to `bias`
pulls levels towards mid-range, where the saddles between wires are,
without adding more of them. 1.0 is plain linear spacing; much above 1.5
and the middle levels start landing on top of each other.
"""
u = np.linspace(-1.0, 1.0, n)
u = np.sign(u) * np.abs(u) ** bias
mid = 0.5 * (POT_MIN + POT_MAX)
return list(mid + 0.5 * (POT_MAX - POT_MIN) * u)
reader = XMLUnstructuredGridReader(FileName=[INPUT_VTU])
contour_filter = Contour(Input=reader,ContourBy = 'potential')
contour_filter.Isosurfaces = contour_levels(N_CONTOURS_FULL, CONTOUR_BIAS_FULL)
renderView = GetActiveViewOrCreate('RenderView')
renderView.ViewSize = [2000,2000]
renderView.OrientationAxesVisibility = 0 # Hide axis
renderView.UseColorPaletteForBackground=0
renderView.Background = [0.1, 0.1, 0.1] # Set background to dark gray (RGB 0-1)
renderView.MultiSamples = 8 # 0 disables it, 4-8 is usually sufficient
ResetCamera()
contour_display = Show(contour_filter, renderView)
contour_display.LineWidth = LINE_WIDTH_FULL
contour_display.RenderLinesAsTubes = 1 # Makes lines look smoother at high res
#colorbar
contour_display_potentialLUT = GetColorTransferFunction('potential', contour_display, separate=True)
contour_display_potentialLUT.ApplyPreset('Cool to Warm', True)
contour_display.SetScalarBarVisibility(renderView, True)
#axesGrid = renderView.AxesGridrfcxgdtv
#axesGrid.Visibility = 1
#axesGrid.XTitle = "x (mm)"
#axesGrid.YTitle = "y (mm)"
# 1. Get the active view
view = GetActiveView()
# 2. Define your desired coordinate ranges (x_min, x_max, y_min, y_max, z_min, z_max)
x_min, x_max = -0.05, 0.05
y_min, y_max = -0.05, 0.05
z_min, z_max = -0.05, 0.05
# 3. Calculate Center, Position, and Parallel Scale
center = [(x_min + x_max) / 2.0, (y_min + y_max) / 2.0, (z_min + z_max) / 2.0]
# Position the camera far away along Z to look at the center
position = [center[0], center[1], 1.0]
# Parallel scale defines how much of the scene is visible.
# It is usually half the height of the viewed area.
view.CameraParallelScale = max((x_max - x_min), (y_max - y_min))/1.6
# 4. Apply settings
view.CenterOfRotation = center
view.CameraPosition = position
view.CameraFocalPoint = center
view.CameraViewUp = [0.0, 1.0, 0.0] # Y-axis is up
# 5. Enable Parallel Projection (optional, often better for exact mapping)
view.CameraParallelProjection = 1
#ResetCamera()
Render()
SaveScreenshot("contour_output.png")
# Everything from here on is a quadrant view: denser levels, heavier lines.
contour_filter.Isosurfaces = contour_levels(N_CONTOURS_QUARTER, CONTOUR_BIAS_QUARTER)
contour_display.LineWidth = LINE_WIDTH_QUARTER
contour_display.RenderLinesAsTubes = 1
# 1. Get the active view
view = GetActiveView()
# 1. Set the Focal Point to the middle of the quadrant in metres
zoom_center = ZOOM_CENTER
# 2. Tighten the Parallel Scale
view.CameraParallelScale = ZOOM_SCALE
# 3. Position the Camera (0.5m away is fine)
view.CameraPosition = [zoom_center[0], zoom_center[1], 0.5]
view.CameraFocalPoint = zoom_center
view.CameraViewUp = [0.0, 1.0, 0.0]
# Equipotentials over one quadrant, saved before the arrows go on so this and
# Field_output.png below share a camera and overlay exactly.
Render()
SaveScreenshot("contour_quarter_output.png")
# pot_threshold = Threshold(Input=reader)
# pot_threshold.Scalars = ['POINTS', 'potential']
# pot_threshold.ThresholdMethod = 'Above Upper Threshold'
# pot_threshold.UpperThreshold = 100.0
# --- 2. Create the Glyph Filter (The Arrows) ---
# IMPORTANT: Use 'pot_threshold' as the Input, not the 'reader'
glyph = Glyph(Input=contour_filter, GlyphType='Arrow') #
# glyph = Glyph(Input=reader, GlyphType='Arrow') #this uses all field line snot just the ones from the equipotential lines shown
# Orientation Array: Use the 'electric field' vector from Elmer
glyph.OrientationArray = ['POINTS', 'electric field']
glyph.ScaleArray = ['POINTS', 'No scale array']
glyph.ScaleFactor = 0.001
glyph.GlyphMode = 'Every Nth Point'
glyph.Stride = GLYPH_STRIDE
# --- 3. Display the Glyphs ---
glyph_display = Show(glyph, renderView)
# Set the representation to Surface so we see the full arrow colors
glyph_display.Representation = 'Surface'
# This is the critical line: Color the arrows by the 'potential' scalar
ColorBy(glyph_display, ('POINTS', 'potential'))
glyph_display.LookupTable = contour_display_potentialLUT
contour_display_potentialLUT.RescaleTransferFunction(POT_MIN, POT_MAX)
# Optional: Disable the scalar bar for the arrows to avoid cluttering
# the existing 'potential' scalar bar.
glyph_display.SetScalarBarVisibility(renderView, False)
# --- 4. Final Render ---
Render()
SaveScreenshot("Field_output.png")
# --- Streamlines over the same quadrant ---
# Field lines rather than arrows: with no B field the drift velocity is
# parallel to E, so these are drift paths up to diffusion, i.e. a map of which
# wire collects charge from where. The glyphs above are fixed length, so they
# show direction only. Quadrant only; over the whole PC it is an unreadable mat.
# Equipotentials the streamlines start from. One level near the anodes seeds
# lines only in a ring around each anode, so with the lines truncated short the
# rest of the frame comes out empty. Spanning the range instead puts seeds
# right across the gas: every equipotential is a closed curve winding between
# the wires, so together they cover the volume.
SEED_POTENTIALS = [660.0, 600.0, 550.0, 500.0, 450.0, 400.0,350.0, 300.0,250.0, 250.0, 200.0, 150.0, 100.0, 50.0]
# Keep 1 seed point in N along the seed contours. Measured point counts per
# level, for working out the total:
#
# 600 V 4970 300 V 29971
# 500 V 8861 200 V 51558
# 400 V 16331 100 V 51645
# 50 V 27259
#
# 250 V and 150 V are not measured; from the trend they are of order 40000 and
# 50000, putting the nine levels near 280000 points. Stride 3 is then ~94000
# seeds, of which roughly an eighth land in the rendered quadrant. That is
# three times the previous seed count, but each line is now 4 mm instead of
# 20 mm, so the integration work is comparable.
SEED_STRIDE = 3
# Arc length each line is allowed to run, in metres. Field lines terminate on
# electrodes, so any line long enough to reach one will converge with every
# other line reaching the same wire -- that convergence is the field, not a
# plotting artefact, and the only way to avoid drawing it is to stop the lines
# short. The anode-cathode gap runs 4.3-6.2 mm depending on z, so 3 mm keeps
# every line clear of the cathodes. Raise it towards 0.005 for longer lines,
# and they will start meeting again at the wires.
# Short lines, and the gaps between them closed by seeding more planes rather
# than by making each line longer. 4 mm is just under the 4.3 mm closest
# anode-cathode approach, so no line quite reaches a wire and they stay
# separate instead of converging.
STREAM_MAX_LENGTH = 0.0005
# StreamTracer counts steps as well as length, and its step sizes are in
# cell-length units rather than metres: 0.2 of a cell by default, and cells are
# 0.05 mm at the wires. 2000 steps therefore buys about 20 mm at best and less
# wherever the mesh is fine, so the default caps the lines before
# STREAM_MAX_LENGTH ever does. Raise it well past what the length needs.
MAX_STEPS = 20000
STREAM_DIRECTION = 'BOTH' # 'BOTH' also draws the half that runs into the anode
STREAM_RANGE = [-200.0, 650.0] # full electrode span, needle to anode
# Clear the quadrant view of everything else so only the field lines show.
Hide(glyph, renderView)
Hide(contour_filter, renderView)
seed_contour = Contour(Input=reader, ContourBy=['POINTS', 'potential'])
seed_contour.Isosurfaces = SEED_POTENTIALS
# StreamTracer's own Point Cloud and Line seeds are 3D and this mesh is a
# single plane at z = 0, so they would mostly land outside it. Seeding from a
# contour of the mesh keeps every seed in the plane by construction.
seed_points = MaskPoints(Input=seed_contour)
seed_points.OnRatio = SEED_STRIDE
seed_points.RandomSampling = 0
stream = StreamTracerWithCustomSource(Input=reader, SeedSource=seed_points)
stream.Vectors = ['POINTS', 'electric field']
# FORWARD follows E, which runs from the anode outwards, so each line leaves
# its seed and heads for a cathode. With BOTH, the backward half of every line
# also climbs to the anode the seed ring encircles, and all of them meet there
# -- that is the joining. BOTH is still the honest full field line if you want
# it; this only changes what gets drawn.
stream.IntegrationDirection = STREAM_DIRECTION
stream.MaximumStreamlineLength = STREAM_MAX_LENGTH
stream.MaximumSteps = MAX_STEPS
# Keep integration in the z = 0 plane. Newer ParaView only, so tolerate it
# being absent.
try:
stream.SurfaceStreamlines = 1
except Exception as exc:
print("note: SurfaceStreamlines unavailable (%s)" % exc)
stream_display = Show(stream, renderView)
stream_display.Representation = 'Surface'
stream_display.LineWidth = STREAM_LINE_WIDTH
stream_display.RenderLinesAsTubes = 1
ColorBy(stream_display, ('POINTS', 'potential'))
streamLUT = GetColorTransferFunction('potential', stream_display, separate=True)
streamLUT.ApplyPreset('Cool to Warm', True)
streamLUT.RescaleTransferFunction(STREAM_RANGE[0], STREAM_RANGE[1])
stream_display.LookupTable = streamLUT
stream_display.SetScalarBarVisibility(renderView, True)
renderView.Background = [0.0, 0.0, 0.0]
Render()
SaveScreenshot("Streamlines_quarter_output.png")

113
anasen_fem/run.py Executable file
View File

@ -0,0 +1,113 @@
import os
import sys
# Cathode wire (0..23) that wires2d_weight.sif drives to 1 V. Passed to the
# mesher, which puts that one wire in its own physical group, tag 40.
SELECTED_CATHODE = 1
# 0 = everything in one pass
# 1 = mesh and the physical field only
# 2 = weighting field and dot product only, reusing stage 1's mesh
STAGE = 0
# gmsh comes from apt and lives in the system python3; meshio is pip-installed
# into the venv, which cannot see apt packages. Neither interpreter has both,
# so name them explicitly rather than relying on whichever python3 is on PATH.
MESH_PY = "/usr/bin/python3"
DOT_PY = os.path.expanduser("~/myenv/bin/python3")
def run(cmd):
"""os.system that stops on failure.
Worth the four lines: a solve that quietly did nothing once produced a
field of zeros, and every later step ran happily on it.
"""
print(cmd)
if os.system(cmd) != 0:
sys.exit("failed: " + cmd)
# z-loci to run, in mm.
#
# The wires twist: over z = 0 -> 174.3 the anode lattice turns 60 deg against
# the cathode lattice, which is exactly 4 cathode pitches of 15 deg. So the
# field pattern goes through the same cycle four times across that range, while
# the wire radii drift slowly and monotonically (anodes 32.0 -> 37.0 mm).
#
# A uniform 17.43 step samples the fast cycle 2.75 times per period, which
# aliases it -- consecutive slices land at relative azimuths 7.5, 14.1, 5.7,
# 12.2, 3.5 deg, jumping around rather than sweeping. Sample the two variations
# separately instead:
# - 8 slices across one pitch, which walks the azimuth in even ~2 deg steps
# at essentially fixed radius
# - 5 slices one whole pitch apart, which holds the azimuth near-fixed and
# walks the radius over its full range
# 12 z-loci in total, against 11 for the uniform sweep.
PITCH_Z = 174.3 / 4.0
Z_VALUES = sorted(set(
[round(i * PITCH_Z / 8.0, 4) for i in range(8)]
+ [round(i * PITCH_Z, 4) for i in range(5)]
))
# Running only two loci for now; delete this line for the full sweep.
# 19.794 is the crossover: the relative azimuth wraps through zero there, so an
# anode sits directly radially outside a cathode, and the closest anode-cathode
# approach over the whole range (4.339 mm) is at 19.707. It is deliberately off
# the grid above, whose nearest point is 21.7875.
# Z_VALUES = [19.690]
# Stage 2 reuses whatever single mesh is sitting in wires2d/, so it cannot span
# several z. Without this it would happily solve the weighting field on one z's
# mesh and archive the result under another z's name -- and dotproduct.py could
# not catch it, since the node sets would agree perfectly.
if STAGE == 2 and len(Z_VALUES) > 1:
sys.exit(
"STAGE 2 applies to the one mesh in wires2d/, which is whichever z\n"
"stage 1 ran last. Set Z_VALUES to that single z."
)
for count, val in enumerate(Z_VALUES, start=10):
print(val)
os.system("mkdir -p wires2d/mesh_files wires2d/sif_files wires2d/vtu_files png")
# Each stage archives its own output before the next one starts, so a
# failure in stage 2 does not throw away what stage 1 already produced.
if STAGE in (0, 1):
run("%s wires_gmsh2d_bc.py %s %d" % (MESH_PY, val, SELECTED_CATHODE))
run("ElmerGrid 14 2 wires2d.msh -2d")
run("ElmerSolver wires2d.sif")
run("./paraview_plotter.py")
os.system("cp wires2d.msh wires2d/mesh_files/wires2d%02d_%1.4f.msh"%(count,val))
os.system("cp wires2d.sif wires2d/sif_files/wires2d_%02d_%1.4f.sif"%(count,val))
os.system("cp wires2d/elfield_anasen_t0001.vtu wires2d/vtu_files/elfield_anasen_%02d_%1.4f.vtu"%(count,val))
os.system("cp contour_output.png png/Contour_output_z_%02d_%1.4f.png"%(count,val))
os.system("cp contour_quarter_output.png png/Contour_output_z_%02d_%1.4f_quarter.png"%(count,val))
os.system("cp Field_output.png png/Field_ouput_z_%02d_%1.4f.png"%(count,val))
os.system("cp Streamlines_quarter_output.png png/Streamlines_output_z_%02d_%1.4f_quarter.png"%(count,val))
# Stage 2 does not re-mesh: it reuses wires2d/ as stage 1 left it, which is
# what makes the node-by-node dot product valid.
if STAGE in (0, 2):
run("ElmerSolver wires2d_weight.sif")
run("%s dotproduct.py" % DOT_PY)
run("./paraview_dotproduct.py")
os.system("cp wires2d_weight.sif wires2d/sif_files/wires2d_weight_%02d_%1.4f.sif"%(count,val))
os.system("cp wires2d/elfield_weight_t0001.vtu wires2d/vtu_files/elfield_weight_%02d_%1.4f.vtu"%(count,val))
os.system("cp wires2d/dotproduct.vtu wires2d/vtu_files/dotproduct_%02d_%1.4f.vtu"%(count,val))
os.system("cp DotProduct_output.png png/DotProduct_output_z_%02d_%1.4f.png"%(count,val))
os.system("cp DotProduct_quarter_output.png png/DotProduct_output_z_%02d_%1.4f_quarter.png"%(count,val))
# os.system("python3 garfield_sim.py")
# (a bare "break" here runs only the first z, as the original did)
# os.system("tar -cvzf wiress2d/mesh.tar.gz wires2d/mesh_files")
# os.system("rm -rf wires2d/mesh_files/*")
# os.system("tar -cvzf wires2d/sif.tar.gz wires2d/sif_files")
# os.system("rm -rf wires2d/sif_files/*")
# os.system("tar -cvzf wires2d/vtu.tar.gz wires2d/vtu_files")
# os.system("rm -rf wires2d/vtu_files/*")

1
anasen_fem/scalars.dat Executable file
View File

@ -0,0 +1 @@
8.500000000000E+002

8
anasen_fem/scalars.dat.names Executable file
View File

@ -0,0 +1,8 @@
Metadata for SaveScalars file: ./scalars.dat
Elmer version: 26.2
Elmer compilation date: 2026-06-10
Solver input file: wires2d.sif
File started at: 2026/09/23 14:27:47
Variables in columns of matrix:
1: res: potential difference

View File

@ -0,0 +1 @@
1.000000000000E+000

View File

@ -0,0 +1,8 @@
Metadata for SaveScalars file: ./scalars_weight.dat
Elmer version: 26.2
Elmer compilation date: 2026-06-10
Solver input file: wires2d_weight.sif
File started at: 2026/09/23 14:50:46
Variables in columns of matrix:
1: res: potential difference

127
anasen_fem/wires2d.sif Executable file
View File

@ -0,0 +1,127 @@
Check Keywords Warn
Header
Mesh DB "." "wires2d"
End
Simulation
Coordinate System = Cartesian 2D
Simulation Type = Steady State
Steady State Max Iterations = 1
Output File = "elstatics.result"
Post File = "elstatics.ep"
Coordinate Scaling = 0.001 ! Converts mm from Gmsh to meters for Elmer
End
Constants
Permittivity Of Vacuum = 8.8542e-12
End
Body 1
Target Bodies(1) = 13
Equation = 1
Material = 1
End
Equation 1
Active Solvers(2) = 1 2
End
Material 1
Relative Permittivity = 1
End
Solver 1
Equation = Electrostatics
Procedure = "StatElecSolve" "StatElecSolver"
Variable = Potential
Variable DOFs = 1
Calculate Electric Field = True
Calculate Electric Flux = False
Linear System Solver = Iterative
Linear System Iterative Method = CG
Linear System Max Iterations = 5000
Linear System Convergence Tolerance = 1.0e-8
Linear System Preconditioning = ILU1
Calculate Vectors = Logical True
End
Solver 2
Equation = "Electric Field"
Procedure = "FluxSolver" "FluxSolver"
! Calculate from the potential
Target Variable = "Potential"
! Name of the output vector field in VTU
Flux Variable = String "Electric Field"
! Use 2D components (x, y)
Flux Coefficient = String "Permittivity"
Calculate Vectors = Logical True
End
Solver 3
Equation = Result Output
Procedure = "ResultOutputSolve" "ResultOutputSolver"
Output File Name = elfield_anasen ! Sets prefix for output files
Output Format = Vtu
! Optional: Select specific variables to save
Scalar Field 1 = Potential
Vector Field 1 = Electric Field
End
Solver 4
Exec Solver = After All
Equation = SaveScalars
Procedure = "SaveData" "SaveScalars"
Filename = "scalars.dat"
End
Boundary Condition 1
Target Boundaries = 1
Potential = -200
Calculate Electric Force = True
End
Boundary Condition 2
Target Boundaries = 2
Potential = 150
Calculate Electric Force = True
End
Boundary Condition 3
Target Boundaries = 3
Potential = 250
Calculate Electric Force = True
End
Boundary Condition 4
Target Boundaries = 10
Potential = 0
End
Boundary Condition 5
Target Boundaries = 20
Potential = 660
Calculate Electric Force = True
End
Boundary Condition 6
Target Boundaries = 30
Potential = 0
End
! The one cathode singled out in wires_gmsh2d_bc.py. Grounded here, exactly
! like the other 23; it is only separate so wires2d_weight.sif can drive it.
Boundary Condition 7
Target Boundaries = 40
Potential = 0
End

View File

@ -0,0 +1,132 @@
Check Keywords Warn
! Ramo weighting potential for the single cathode at tag 40: that electrode
! sits at 1 V and every other one at 0 V. Identical to wires2d.sif apart from
! the potentials and the output names, so both solves discretise the same way
! and E . E_w is meaningful node by node.
Header
Mesh DB "." "wires2d"
End
Simulation
Coordinate System = Cartesian 2D
Simulation Type = Steady State
Steady State Max Iterations = 1
Output File = "elstatics_weight.result"
Post File = "elstatics_weight.ep"
Coordinate Scaling = 0.001 ! Converts mm from Gmsh to meters for Elmer
End
Constants
Permittivity Of Vacuum = 8.8542e-12
End
Body 1
Target Bodies(1) = 13
Equation = 1
Material = 1
End
Equation 1
Active Solvers(2) = 1 2
End
Material 1
Relative Permittivity = 1
End
Solver 1
Equation = Electrostatics
Procedure = "StatElecSolve" "StatElecSolver"
Variable = Potential
Variable DOFs = 1
Calculate Electric Field = True
Calculate Electric Flux = False
Linear System Solver = Iterative
Linear System Iterative Method = CG
Linear System Max Iterations = 5000
Linear System Convergence Tolerance = 1.0e-8
Linear System Preconditioning = ILU1
Calculate Vectors = Logical True
End
Solver 2
Equation = "Electric Field"
Procedure = "FluxSolver" "FluxSolver"
! Calculate from the potential
Target Variable = "Potential"
! Name of the output vector field in VTU
Flux Variable = String "Electric Field"
! Use 2D components (x, y)
Flux Coefficient = String "Permittivity"
Calculate Vectors = Logical True
End
Solver 3
Equation = Result Output
Procedure = "ResultOutputSolve" "ResultOutputSolver"
Output File Name = elfield_weight ! Sets prefix for output files
Output Format = Vtu
! Optional: Select specific variables to save
Scalar Field 1 = Potential
Vector Field 1 = Electric Field
End
Solver 4
Exec Solver = After All
Equation = SaveScalars
Procedure = "SaveData" "SaveScalars"
Filename = "scalars_weight.dat"
End
Boundary Condition 1
Target Boundaries = 1
Potential = 0
Calculate Electric Force = True
End
Boundary Condition 2
Target Boundaries = 2
Potential = 0
Calculate Electric Force = True
End
Boundary Condition 3
Target Boundaries = 3
Potential = 0
Calculate Electric Force = True
End
Boundary Condition 4
Target Boundaries = 10
Potential = 0
End
Boundary Condition 5
Target Boundaries = 20
Potential = 0
Calculate Electric Force = True
End
Boundary Condition 6
Target Boundaries = 30
Potential = 0
End
! The one cathode singled out in wires_gmsh2d_bc.py. Grounded here, exactly
! like the other 23; it is only separate so wires2d_weight.sif can drive it.
Boundary Condition 7
Target Boundaries = 40
Potential = 1
End

295
anasen_fem/wires_gmsh2d_bc.py Executable file
View File

@ -0,0 +1,295 @@
# This script generates a 2D Gmsh geometry for the ANASEN detector's wire planes, including an optional hot needle and IC wires. The geometry is designed for adaptive meshing, with finer mesh near the wires and coarser mesh in empty space. The script takes a z-locus as a command-line argument to determine the interpolation between the two wire planes.
import numpy as np
import gmsh, sys
# --- Configuration Flags ---
include_ic_wires = True
include_needle = True
gmsh.initialize()
gmsh.model.add("adaptive_mesh")
gmsh.option.setNumber("General.NumThreads", 10)
# gmsh.option.setNumber("Mesh.Adapt.MaxNumberOfElements", 200000)
# gmsh.option.setNumber("Mesh.Adapt.MaxNumberOfNodes", 200000)
# gmsh.option.setNumber("Mesh.Adapt.MaxIter",5)
# gmsh.option.setNumber("Mesh.MeshSizeMin", 5e-3)
# gmsh.option.setNumber("Mesh.MeshSizeMax", 10.0)
gmsh.option.setNumber("Geometry.Tolerance", 4e-2)
# gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0)
# Only needed alongside mesh.recombine(), which is off. See the note there.
# gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 2)
# gmsh.option.setNumber("Mesh.SubdivisionAlgorithm", 1)
gmsh.option.setNumber("Mesh.SecondOrderIncomplete", 1)
lc = 0.04
# z_loc = -174.3
if len(sys.argv) < 2:
print("Usage: python3 wires_gmsh2d_bc.py <z_locus in mm> [selected_cathode_index]")
quit()
z_loc = float(sys.argv[1])
# Cathode wire (0..23) given its own physical group, tag 40, so that
# wires2d_weight.sif can hold it at 1 V while everything else stays grounded.
selected_cathode = int(sys.argv[2]) if len(sys.argv) > 2 else 1
wireShift = 4.0
k = 2 * np.pi / 24.0
kg = k/2.0
# Plane 1 Offsets (-zmax/2)
# Anodes: -6*k (base) - 4*k (correction) = -10*k
offset_a1 = -6 * k - 4 * k
# Cathodes: -6*k (base) + 0.5*k (half-placement)
offset_c1 = -6 * k + (k / 2.0)
# Guard wires: aligned with cathodes
offset_g1 = offset_c1
# Plane 2 Offsets (+zmax/2) with Twist
offset_a2 = offset_a1 + (wireShift * k)
offset_c2 = offset_c1 - (wireShift * k)
offset_g2 = offset_c2
# 1 needle, 24 ic1, 24 ic2, 48 guard wires, 24 anodes, 24 cathodes
# needle at plane 1 at -zmax/2 no rotation
xarr_needle = np.array([0])
yarr_needle = np.array([0])
# ic1 wires, plane 1 at -zmax/2 no rotation
xarr_i11 = np.array([23 * np.cos(k * i) for i in range(24)])
yarr_i11 = np.array([23 * np.sin(k * i) for i in range(24)])
# ic1 wires, plane 1 at -zmax/2 no rotation
xarr_i21 = np.array([23 * np.cos(k * i + k / 2.0) for i in range(24)])
yarr_i21 = np.array([23 * np.sin(k * i + k / 2.0) for i in range(24)])
# --- Coordinate Arrays (Plane 1) ---
# Anodes: -k*i (Left-handed twist direction)
xarra_1 = np.array([37 * np.cos(-k * i + offset_a1) for i in range(24)])
yarra_1 = np.array([37 * np.sin(-k * i + offset_a1) for i in range(24)])
# Cathodes: +k*i (Right-handed twist direction)
xarrc_1 = np.array([42 * np.cos(k * i + offset_c1) for i in range(24)])
yarrc_1 = np.array([42 * np.sin(k * i + offset_c1) for i in range(24)])
# Guard Wires (48 wires, use kg spacing)
xarrg_1 = np.array([32 * np.cos(kg * i + offset_g1) for i in range(48)])
yarrg_1 = np.array([32 * np.sin(kg * i + offset_g1) for i in range(48)])
# needle at plane 2 at zmax/2
xarr_needle_2 = np.array([0])
yarr_needle_2 = np.array([0])
# #ic1 wires, plane 2 at zmax/2
xarr_i12 = np.array([23 * np.cos(k * i) for i in range(24)])
yarr_i12 = np.array([23 * np.sin(k * i) for i in range(24)])
# #ic2 wires, plane 2 at zmax/2
xarr_i22 = np.array([23 * np.cos(k * i + k / 2.0) for i in range(24)])
yarr_i22 = np.array([23 * np.sin(k * i + k / 2.0) for i in range(24)])
# --- Coordinate Arrays (Plane 2) ---
xarra_2 = np.array([37 * np.cos(-k * i + offset_a2) for i in range(24)])
yarra_2 = np.array([37 * np.sin(-k * i + offset_a2) for i in range(24)])
xarrc_2 = np.array([42 * np.cos(k * i + offset_c2) for i in range(24)])
yarrc_2 = np.array([42 * np.sin(k * i + offset_c2) for i in range(24)])
xarrg_2 = np.array([32 * np.cos(kg * i + offset_g2) for i in range(48)])
yarrg_2 = np.array([32 * np.sin(kg * i + offset_g2) for i in range(48)])
direction_needle_x = xarr_needle_2 - xarr_needle
direction_needle_y = yarr_needle_2 - yarr_needle
direction_ic1_x = xarr_i12 - xarr_i11
direction_ic1_y = yarr_i12 - yarr_i11
direction_ic2_x = xarr_i22 - xarr_i21
direction_ic2_y = yarr_i22 - yarr_i21
direction_guard_x = xarrg_2 - xarrg_1
direction_guard_y = yarrg_2 - yarrg_1
direction_anodes_x = xarra_2 - xarra_1
direction_anodes_y = yarra_2 - yarra_1
direction_cathodes_x = xarrc_2 - xarrc_1
direction_cathodes_y = yarrc_2 - yarrc_1
t = (z_loc + 174.3) / (2 * 174.3) # z=-174.3 is 0, z=+174.3 is 1
xloc_needle = xarr_needle + t * direction_needle_x
yloc_needle = yarr_needle + t * direction_needle_y
xloc_i1 = xarr_i11 + t * direction_ic1_x
yloc_i1 = yarr_i11 + t * direction_ic1_y
xloc_i2 = xarr_i21 + t * direction_ic2_x
yloc_i2 = yarr_i21 + t * direction_ic2_y
xloc_g = xarrg_1 + t * direction_guard_x
yloc_g = yarrg_1 + t * direction_guard_y
xloc_a = xarra_1 + t * direction_anodes_x
yloc_a = yarra_1 + t * direction_anodes_y
xloc_c = xarrc_1 + t * direction_cathodes_x
yloc_c = yarrc_1 + t * direction_cathodes_y
# wire_radius_a = 0.018 #mm
# wire_radius_c = 0.0762 #mm
# wire_radius_g = 0.0762 #mm
wire_radius = 0.254 # mm
needle = []
ic1_wires = []
ic2_wires = []
guard_wires = []
anode_wires = []
cathode_wires = []
iw1_tags = [(3, i) for i in range(24)]
iw2_tags = [(3, i + 24) for i in range(24)]
gw_tags = [(3, i + 48) for i in range(48)]
aw_tags = [(3, i) for i in range(24)]
cw_tags = [(3, i + 24) for i in range(24)]
# for i,[xa,ya,xc,yc] in enumerate(zip(xarra_1,yarra_1,xarrc_1,yarrc_1)):
# create Hot Needle (1 total)
for i, (xn, yn) in enumerate(zip(xloc_needle, yloc_needle)):
if include_needle:
ndisk = gmsh.model.occ.addDisk(xn, yn, 0, wire_radius, wire_radius)
needle.append(ndisk)
# create Guard Wires (48 total)
for xg, yg in zip(xloc_g, yloc_g):
gdisk = gmsh.model.occ.addDisk(xg, yg, 0, wire_radius, wire_radius)
guard_wires.append(gdisk)
# create Cathode Wires (24 total)
for xc, yc in zip(xloc_c, yloc_c):
cdisk = gmsh.model.occ.addDisk(xc, yc, 0, wire_radius, wire_radius)
cathode_wires.append(cdisk)
# create IC Anode and Cathode Wires (24 total each)
for i, (xa, ya) in enumerate(zip(xloc_a, yloc_a)):
adisk = gmsh.model.occ.addDisk(xa, ya, 0, wire_radius, wire_radius)
anode_wires.append(adisk)
# Place IC wires only if flag is True
if include_ic_wires:
i1disk = gmsh.model.occ.addDisk(
xloc_i1[i], yloc_i1[i], 0, wire_radius, wire_radius
)
i2disk = gmsh.model.occ.addDisk(
xloc_i2[i], yloc_i2[i], 0, wire_radius, wire_radius
)
ic1_wires.append(i1disk)
ic2_wires.append(i2disk)
anasen_barrel = gmsh.model.occ.addDisk(0, 0, 0, 500, 500)
# gmsh.model.occ.synchronize()
# gmsh.model.mesh.embed(1,anode_wires+cathode_wires,2,anasen_barrel)
gmsh.option.setNumber("Geometry.Tolerance", 1e-6)
gmsh.option.setNumber("Geometry.OCCFixDegenerated", 1)
gmsh.model.occ.synchronize()
# --- Surface Extraction ---
def get_surfs(disks):
surfs = []
for d in disks:
surfs += [
s[1] for s in gmsh.model.getBoundary([(2, d)], oriented=False) if s[0] == 1
]
return surfs
if not 0 <= selected_cathode < len(cathode_wires):
print("selected_cathode must be 0..%d" % (len(cathode_wires) - 1))
quit()
cathode_wires_other = [
disk for i, disk in enumerate(cathode_wires) if i != selected_cathode
]
# Cut the wire disks into the gas disk, replacing the old mesh.embed() call.
# embed only makes the mesher honour the curves; fragment splits the barrel
# into conforming surfaces, which is what lets one wire carry its own BC.
gmsh.model.occ.synchronize()
all_wire_disks = needle + guard_wires + cathode_wires + anode_wires
if include_ic_wires:
all_wire_disks += ic1_wires + ic2_wires
gmsh.model.occ.fragment([(2, anasen_barrel)], [(2, d) for d in all_wire_disks])
gmsh.model.occ.synchronize()
# fragment re-derives the bounding curves, so re-extract them.
needle_surfs = get_surfs(needle) if include_needle else []
gwire_surfs = get_surfs(guard_wires)
awire_surfs = get_surfs(anode_wires)
cwire_surfs = get_surfs(cathode_wires_other)
cwire_sel_surfs = get_surfs([cathode_wires[selected_cathode]])
i1wire_surfs = get_surfs(ic1_wires) if include_ic_wires else []
i2wire_surfs = get_surfs(ic2_wires) if include_ic_wires else []
all_active_wire_surfs = (
needle_surfs
+ gwire_surfs
+ awire_surfs
+ cwire_surfs
+ cwire_sel_surfs
+ i1wire_surfs
+ i2wire_surfs
)
f1 = gmsh.model.mesh.field.add("Distance")
gmsh.model.mesh.field.setNumbers(f1, "CurvesList", all_active_wire_surfs)
f2 = gmsh.model.mesh.field.add("Threshold")
gmsh.model.mesh.field.setNumber(f2, "InField", f1)
gmsh.model.mesh.field.setNumber(f2, "SizeMin", 0.05) # Fine mesh near wires
gmsh.model.mesh.field.setNumber(f2, "SizeMax", 5.0) # Large mesh in empty space
gmsh.model.mesh.field.setNumber(f2, "DistMin", 0.5) # Apply SizeMin within 1mm
gmsh.model.mesh.field.setNumber(f2, "DistMax", 15.0) # Transition to SizeMax by 20mm
gmsh.model.mesh.field.setAsBackgroundMesh(f2)
# --- Physical Groups ---
# These tags are the Target Bodies / Target Boundaries numbers in the .sif
# files. Do not renumber them without changing both sifs -- and note that
# ElmerGrid's -autoclean renumbers them for you, which silently breaks every
# boundary condition.
# Needle
if include_needle:
gmsh.model.addPhysicalGroup(1, needle_surfs, tag=1, name="hot_needle")
# IC Wires
if include_ic_wires:
gmsh.model.addPhysicalGroup(1, i1wire_surfs, tag=2, name="ic_wire_1")
gmsh.model.addPhysicalGroup(1, i2wire_surfs, tag=3, name="ic_wire_2")
# Proportional Counter Wires
gmsh.model.addPhysicalGroup(1, gwire_surfs, tag=10, name="guard_wires")
gmsh.model.addPhysicalGroup(1, awire_surfs, tag=20, name="anode_wires")
gmsh.model.addPhysicalGroup(1, cwire_surfs, tag=30, name="cathode_wires")
# The one cathode the weighting potential is solved for, kept out of tag 30 so
# wires2d_weight.sif can drive it independently.
gmsh.model.addPhysicalGroup(1, cwire_sel_surfs, tag=40, name="cathode_wire_selected")
# Gas Volume (2D). fragment split the barrel into many surfaces, so collect
# them all; naming the original disk alone would solve one sliver of the domain.
all_surfaces_2d = [s[1] for s in gmsh.model.getEntities(dim=2)]
gmsh.model.addPhysicalGroup(2, all_surfaces_2d, tag=13, name="gas")
gmsh.option.setNumber("Mesh.Algorithm", 5)
gmsh.model.mesh.generate(2)
gmsh.model.mesh.setOrder(2)
# recombine() ran for over half an hour on the barrel surface without
# finishing, and refine() took the mesh to ~16M nodes. Neither is needed: the
# Threshold field above already gives 0.05 mm elements on 0.254 mm wires.
# gmsh.model.mesh.recombine()
# gmsh.model.mesh.refine()
gmsh.write("wires2d.msh")
# gmsh.fltk.run()
gmsh.finalize()

89
centroids_edited.txt Normal file
View File

@ -0,0 +1,89 @@
HistogramIndex PeakNumber Centroid Amplitude Sigma
1 1 922.213
1 2 1885.55
1 3 2845.53
1 4 3810.32
2 1 955.591
2 2 1953.17
2 3 2949.37
2 4 3950.79
3 1 995.787
3 2 2036.58
3 3 3076.91
3 4 4112.05
4 1 1017.48
4 2 2080.19
4 3 3142.24
4 4 4206.1
5 1 1022.78
5 2 2091.21
5 3 3158.28
5 4 4226.97
6 1 1076.22
6 2 2203.37
6 3 3329.53
6 4 4457.69
7 1 977.46
7 2 1998.02
7 3 3017.36
7 4 4040.47
8 1 1049.74
8 2 2144.38
8 3 3238.2
8 4 4335.25
9 1 1000.59
9 2 2046.42
9 3 3090.29
9 4 4129.63
10 1 1014.92
10 2 2076.16
10 3 3134.59
10 4 4213.42
11 1 1004.85
11 2 2052.88
11 3 3100.3
11 4 4164.75
12 1 945.861
12 2 1932.49
12 3 2917.95
12 4 3955.15
13 1 998.307
13 2 2040.38
13 3 3078.76
13 4 4135.51
14 1 966.429
14 2 1972.15
14 3 2974.84
14 4 4056.41
15 1 958.352
15 2 1958.64
15 3 2957.7
15 4 3970.41
16 1 970.732
16 2 1977.63
16 3 2984.97
16 4 4002.56
17 1 1013.65
17 2 2064.9
17 3 3114.19
17 4 4190.98
18 1 975.538
18 2 1990.64
18 3 3005.46
18 4 4048.99
20 1 912.778
20 2 1866.83
20 3 2819.21
20 4 3781.63
21 1 1002.36
21 2 1989.95
21 3 2975.53
21 4 3986.71
22 1 1075.38
22 2 2144.25
22 3 3210.17
22 4 4312.84
23 1 988.828
23 2 2016.35
23 3 3044.19
23 4 4082.41

48
detector_geometry.dat Normal file
View File

@ -0,0 +1,48 @@
=========================================================
SX3 BARREL AZIMUTHAL ANGLES (Degrees)
=========================================================
Det ID | Strip 0 | Strip 1 | Strip 2 | Strip 3 | Det Center
---------------------------------------------------------
0 | 85.08 | 78.39 | 71.61 | 64.92 | 75.00
1 | 55.08 | 48.39 | 41.61 | 34.92 | 45.00
2 | 25.08 | 18.39 | 11.61 | 4.92 | 15.00
3 | -4.92 | -11.61 | -18.39 | -25.08 | -15.00
4 | -34.92 | -41.61 | -48.39 | -55.08 | -45.00
5 | -64.92 | -71.61 | -78.39 | -85.08 | -75.00
6 | -94.92 | -101.61 | -108.39 | -115.08 | -105.00
7 | -124.92 | -131.61 | -138.39 | -145.08 | -135.00
8 | -154.92 | -161.61 | -168.39 | -175.08 | -165.00
9 | 175.08 | 168.39 | 161.61 | 154.92 | 165.00
10 | 145.08 | 138.39 | 131.61 | 124.92 | 135.00
11 | 115.08 | 108.39 | 101.61 | 94.92 | 105.00
=========================================================
PROPORTIONAL COUNTER WIRE ANGLES (Degrees)
=========================================================
Wire ID | Anode (-z) | Anode (+z) | Cathode (-z) | Cathode (+z)
----------------------------------------------------------------
0 | -135.00 | -90.00 | -97.50 | -142.50
1 | -150.00 | -105.00 | -82.50 | -127.50
2 | -165.00 | -120.00 | -67.50 | -112.50
3 | -180.00 | -135.00 | -52.50 | -97.50
4 | 165.00 | -150.00 | -37.50 | -82.50
5 | 150.00 | -165.00 | -22.50 | -67.50
6 | 135.00 | -180.00 | -7.50 | -52.50
7 | 120.00 | 165.00 | 7.50 | -37.50
8 | 105.00 | 150.00 | 22.50 | -22.50
9 | 90.00 | 135.00 | 37.50 | -7.50
10 | 75.00 | 120.00 | 52.50 | 7.50
11 | 60.00 | 105.00 | 67.50 | 22.50
12 | 45.00 | 90.00 | 82.50 | 37.50
13 | 30.00 | 75.00 | 97.50 | 52.50
14 | 15.00 | 60.00 | 112.50 | 67.50
15 | 0.00 | 45.00 | 127.50 | 82.50
16 | -15.00 | 30.00 | 142.50 | 97.50
17 | -30.00 | 15.00 | 157.50 | 112.50
18 | -45.00 | 0.00 | 172.50 | 127.50
19 | -60.00 | -15.00 | -172.50 | 142.50
20 | -75.00 | -30.00 | -157.50 | 157.50
21 | -90.00 | -45.00 | -142.50 | 172.50
22 | -105.00 | -60.00 | -127.50 | -172.50
23 | -120.00 | -75.00 | -112.50 | -157.50

104
eloss_calculations/Eloss.py Normal file
View File

@ -0,0 +1,104 @@
import pycatima as catima
import numpy as np
import os
DEDX_SCALE = float(os.environ.get("DEDX_SCALE", "0.89"))
print(f"Using dEdX scale factor: {DEDX_SCALE}")
# --- 1. Constants ---
P_TORR = 250
TEMP_K = 293.15
R = 8.3144
MEV2U = 1.0 / 931.494
P_CO2 = 3
# Gas Density Calculations
p_pa = P_TORR * 133.322
molar_density = p_pa / (R * TEMP_K)
m_he, m_c, m_o= 4.0026, 12.0000, 15.9949
m_mix_avg = ((1 - P_CO2 / 100) * m_he) + (P_CO2 / 100 * (m_c + 2*m_o))
rho_g_cm3 = (molar_density * m_mix_avg) / 1e6
print(f"Gas density at {P_TORR} Torr: {rho_g_cm3:.6e} g/cm^3")
# --- 2. Material & Step Setup ---
material_def = [(m_he, 2, (1 - P_CO2 / 100)), (m_c, 6, P_CO2 / 100), (m_o, 8, 2*P_CO2 / 100)]
gas_mix = catima.Material(material_def)
gas_mix.density(rho_g_cm3)
# Thickness step settings
step_mg_cm2 = 0.001 # 1 ug/cm2 steps as per your example -- kept fine for
# numerical accuracy of the dedx integration itself.
step_g_cm2 = step_mg_cm2 / 1000.0
max_steps = 1000000000 # Adjust based on how far you want to track
coarse_step_cm = 0.2 # row spacing over most of the track
fine_step_cm = 0.03 # row spacing near the Bragg peak
fine_zone_frac = 0.085 # fraction of the *total* range treated as "near the peak"
def generate_lookup(z, mass_u, e_start_mev, label):
filename = f"/home/vsitaraman/ANASEN_analysis/eloss_calculations/{label}_lookup_{e_start_mev}MeV_{P_TORR}torr_{P_CO2}pc.dat"
header = f"Energy(MeV) \tmg/cm2 \tcm\nStarting Energy: {e_start_mev} MeV"
# Pass 1: integrate at full precision just to find the total range (needed
# to know where the "last fine_zone_frac" of the track begins).
projectile = catima.Projectile(mass_u, z)
e_u = e_start_mev / mass_u
total_thickness_g_cm2 = 0.0
while e_u >= 0.0001:
projectile.T(e_u)
loss_mev = catima.dedx(projectile, gas_mix) * step_g_cm2
e_u = (e_u * mass_u - loss_mev) / mass_u
total_thickness_g_cm2 += step_g_cm2
total_range_cm = total_thickness_g_cm2 / rho_g_cm3
fine_zone_start_cm = total_range_cm * (1.0 - fine_zone_frac)
projectile = catima.Projectile(mass_u, z)
current_e_total = e_start_mev
current_thickness_g_cm2 = 0.0
next_checkpoint_cm = 0.0
output = []
last_dist_cm = None
def append_row(e_total, thickness_g_cm2, dist_cm):
if last_dist_cm is not None and dist_cm <= last_dist_cm:
return False
output.append([e_total, thickness_g_cm2 * 1000.0, dist_cm])
return True
for i in range(max_steps):
dist_cm = current_thickness_g_cm2 / rho_g_cm3
if dist_cm >= next_checkpoint_cm:
if append_row(current_e_total, current_thickness_g_cm2, dist_cm):
last_dist_cm = dist_cm
step_cm = fine_step_cm if dist_cm >= fine_zone_start_cm else coarse_step_cm
next_checkpoint_cm = dist_cm + step_cm
e_u = current_e_total / mass_u
if e_u < 0.0001: # Stop at ATIMA limit
append_row(current_e_total, current_thickness_g_cm2, dist_cm)
break
projectile.T(e_u)
# dedx returns MeV / (g/cm2)
loss_mev = catima.dedx(projectile, gas_mix) * step_g_cm2 * DEDX_SCALE
# if(mass_u >=10.0):
# loss_mev = catima.dedx(projectile, gas_mix) * step_g_cm2 * DEDX_SCALE
# else:
# loss_mev = catima.dedx(projectile, gas_mix) * step_g_cm2
current_e_total = max(0.0, current_e_total - loss_mev)
current_thickness_g_cm2 += step_g_cm2
np.savetxt(filename, output, fmt='%.6f', delimiter='\t', header=header)
print(f"Lookup table created: {filename} ({len(output)} rows, "
f"range {total_range_cm:.2f} cm, fine zone below {fine_zone_start_cm:.2f} cm)")
# --- 3. Run ---
# Format: generate_lookup(Z, mass_u, E_start_MeV, label)
generate_lookup(1, 1.0078, 30, "proton")
generate_lookup(1, 2.01355, 30, "deutron")
generate_lookup(2, 4.0026, 50, "alpha")
generate_lookup(13,26.9815, 80, "aluminum")
generate_lookup(9,17.0021, 70, "fluorine")
generate_lookup(8,15.9949, 70, "oxygen")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,579 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 80 MeV
80.000000 0.000000 0.000000
79.792337 0.015000 0.210854
79.584426 0.030000 0.421708
79.376267 0.045000 0.632562
79.167859 0.060000 0.843416
78.959201 0.075000 1.054270
78.750292 0.090000 1.265124
78.541131 0.105000 1.475978
78.331717 0.120000 1.686832
78.122050 0.135000 1.897686
77.912127 0.150000 2.108540
77.701950 0.165000 2.319394
77.491515 0.180000 2.530248
77.280823 0.195000 2.741102
77.069873 0.210000 2.951956
76.858662 0.225000 3.162810
76.647192 0.240000 3.373664
76.435460 0.255000 3.584518
76.223465 0.270000 3.795372
76.011207 0.285000 4.006226
75.798684 0.300000 4.217080
75.585896 0.315000 4.427934
75.372842 0.330000 4.638788
75.159519 0.345000 4.849642
74.945928 0.360000 5.060496
74.732068 0.375000 5.271350
74.517937 0.390000 5.482204
74.303534 0.405000 5.693058
74.088858 0.420000 5.903912
73.873908 0.435000 6.114766
73.658683 0.450000 6.325620
73.443182 0.465000 6.536474
73.227404 0.480000 6.747328
73.011348 0.495000 6.958182
72.795012 0.510000 7.169036
72.578396 0.525000 7.379890
72.361498 0.540000 7.590744
72.144317 0.555000 7.801598
71.926853 0.570000 8.012452
71.709103 0.585000 8.223306
71.491067 0.600000 8.434160
71.272744 0.615000 8.645014
71.054132 0.630000 8.855868
70.835231 0.645000 9.066722
70.616038 0.660000 9.277576
70.396554 0.675000 9.488430
70.176776 0.690000 9.699284
69.956703 0.705000 9.910138
69.736335 0.720000 10.120992
69.515669 0.735000 10.331846
69.294705 0.750000 10.542700
69.073442 0.765000 10.753554
68.851878 0.780000 10.964408
68.630012 0.795000 11.175262
68.407842 0.810000 11.386116
68.185368 0.825000 11.596970
67.962588 0.840000 11.807825
67.739500 0.855000 12.018679
67.516104 0.870000 12.229533
67.292398 0.885000 12.440387
67.068381 0.900000 12.651241
66.844051 0.915000 12.862095
66.619407 0.930000 13.072949
66.394447 0.945000 13.283803
66.169171 0.960000 13.494657
65.943577 0.975000 13.705511
65.717663 0.990000 13.916365
65.491428 1.005000 14.127219
65.264871 1.020000 14.338073
65.037989 1.035000 14.548927
64.810783 1.050000 14.759781
64.583249 1.065000 14.970635
64.355388 1.080000 15.181489
64.127196 1.095000 15.392343
63.898673 1.110000 15.603197
63.669818 1.125000 15.814051
63.440628 1.140000 16.024905
63.211102 1.155000 16.235759
62.981239 1.170000 16.446613
62.751037 1.185000 16.657467
62.520494 1.200000 16.868321
62.289609 1.215000 17.079175
62.058380 1.230000 17.290029
61.826806 1.245000 17.500883
61.594885 1.260000 17.711737
61.362615 1.275000 17.922591
61.129994 1.290000 18.133445
60.897022 1.305000 18.344299
60.663696 1.320000 18.555153
60.430014 1.335000 18.766007
60.195975 1.350000 18.976861
59.961578 1.365000 19.187715
59.726819 1.380000 19.398569
59.491698 1.395000 19.609423
59.256213 1.410000 19.820277
59.020362 1.425000 20.031131
58.784142 1.440000 20.241985
58.547554 1.455000 20.452839
58.310593 1.470000 20.663693
58.073259 1.485000 20.874547
57.835549 1.500000 21.085401
57.597463 1.515000 21.296255
57.358997 1.530000 21.507109
57.120149 1.545000 21.717963
56.880919 1.560000 21.928817
56.641304 1.575000 22.139671
56.401301 1.590000 22.350525
56.160909 1.605000 22.561379
55.920126 1.620000 22.772233
55.678949 1.635000 22.983087
55.437377 1.650000 23.193941
55.195408 1.665000 23.404795
54.953038 1.680000 23.615649
54.710267 1.695000 23.826503
54.467092 1.710000 24.037357
54.223511 1.725000 24.248211
53.979521 1.740000 24.459065
53.735120 1.755000 24.669919
53.490307 1.770000 24.880773
53.245078 1.785000 25.091627
52.999431 1.800000 25.302481
52.753364 1.815000 25.513335
52.506875 1.830000 25.724189
52.259961 1.845000 25.935043
52.012620 1.860000 26.145897
51.764849 1.875000 26.356751
51.516645 1.890000 26.567605
51.268007 1.905000 26.778459
51.018932 1.920000 26.989313
50.769416 1.935000 27.200167
50.519458 1.950000 27.411021
50.269055 1.965000 27.621875
50.018204 1.980000 27.832729
49.766902 1.995000 28.043583
49.515147 2.010000 28.254437
49.262935 2.025000 28.465291
49.010265 2.040000 28.676145
48.757132 2.055000 28.886999
48.503535 2.070000 29.097853
48.249471 2.085000 29.308707
47.994935 2.100000 29.519561
47.739926 2.115000 29.730415
47.484439 2.130000 29.941269
47.228473 2.145000 30.152123
46.972024 2.160000 30.362977
46.715089 2.175000 30.573831
46.457664 2.190000 30.784685
46.199746 2.205000 30.995539
45.941333 2.220000 31.206393
45.682419 2.235000 31.417247
45.423003 2.250000 31.628101
45.163080 2.265000 31.838955
44.902648 2.280000 32.049809
44.641701 2.295000 32.260663
44.380238 2.310000 32.471517
44.118253 2.325000 32.682371
43.855744 2.340000 32.893225
43.592707 2.355000 33.104079
43.329136 2.370000 33.314933
43.065030 2.385000 33.525787
42.800383 2.400000 33.736641
42.535191 2.415000 33.947495
42.269451 2.430000 34.158349
42.003157 2.445000 34.369203
41.736307 2.460000 34.580057
41.468894 2.475000 34.790911
41.200916 2.490000 35.001765
40.932367 2.505000 35.212619
40.663242 2.520000 35.423474
40.393538 2.535000 35.634328
40.123248 2.550000 35.845182
39.852369 2.565000 36.056036
39.580894 2.580000 36.266890
39.308820 2.595000 36.477744
39.036140 2.610000 36.688598
38.762850 2.625000 36.899452
38.488944 2.640000 37.110306
38.214417 2.655000 37.321160
37.939262 2.670000 37.532014
37.663473 2.685000 37.742868
37.387046 2.700000 37.953722
37.109974 2.715000 38.164576
36.832251 2.730000 38.375430
36.553870 2.745000 38.586284
36.274824 2.760000 38.797138
35.995108 2.775000 39.007992
35.714714 2.790000 39.218846
35.433636 2.805000 39.429700
35.151865 2.820000 39.640554
34.869396 2.835000 39.851408
34.586219 2.850000 40.062262
34.302328 2.865000 40.273116
34.017715 2.880000 40.483970
33.732371 2.895000 40.694824
33.446287 2.910000 40.905678
33.159456 2.925000 41.116532
32.871868 2.940000 41.327386
32.583515 2.955000 41.538240
32.294386 2.970000 41.749094
32.004472 2.985000 41.959948
31.713763 3.000000 42.170802
31.422249 3.015000 42.381656
31.130024 3.030000 42.592510
30.837182 3.045000 42.803364
30.543726 3.060000 43.014218
30.249651 3.075000 43.225072
29.954957 3.090000 43.435926
29.659640 3.105000 43.646780
29.363698 3.120000 43.857634
29.067128 3.135000 44.068488
28.769929 3.150000 44.279342
28.472097 3.165000 44.490196
28.173630 3.180000 44.701050
27.874526 3.195000 44.911904
27.574783 3.210000 45.122758
27.274398 3.225000 45.333612
26.973369 3.240000 45.544466
26.671694 3.255000 45.755320
26.369370 3.270000 45.966174
26.066396 3.285000 46.177028
25.762770 3.300000 46.387882
25.458489 3.315000 46.598736
25.153552 3.330000 46.809590
24.847957 3.345000 47.020444
24.541702 3.360000 47.231298
24.234785 3.375000 47.442152
23.927205 3.390000 47.653006
23.618960 3.405000 47.863860
23.310050 3.420000 48.074714
23.000472 3.435000 48.285568
22.690226 3.450000 48.496422
22.379311 3.465000 48.707276
22.067726 3.480000 48.918130
21.755471 3.495000 49.128984
21.442545 3.510000 49.339838
21.128949 3.525000 49.550692
20.814683 3.540000 49.761546
20.499748 3.555000 49.972400
20.184144 3.570000 50.183254
19.867873 3.585000 50.394108
19.550938 3.600000 50.604962
19.233340 3.615000 50.815816
18.915082 3.630000 51.026670
18.596169 3.645000 51.237524
18.276803 3.660000 51.448378
17.957360 3.675000 51.659232
17.637889 3.690000 51.870086
17.318421 3.705000 52.080940
16.998992 3.720000 52.291794
16.679638 3.735000 52.502648
16.360399 3.750000 52.713502
16.041318 3.765000 52.924356
15.722438 3.780000 53.135210
15.403809 3.795000 53.346064
15.085484 3.810000 53.556918
14.767517 3.825000 53.767772
14.449970 3.840000 53.978626
14.132908 3.855000 54.189480
13.816401 3.870000 54.400334
13.500524 3.885000 54.611188
13.185359 3.900000 54.822042
12.870994 3.915000 55.032896
12.557525 3.930000 55.243750
12.245055 3.945000 55.454604
11.933695 3.960000 55.665458
11.623565 3.975000 55.876312
11.314797 3.990000 56.087166
11.007530 4.005000 56.298020
10.701916 4.020000 56.508874
10.398119 4.035000 56.719728
10.096315 4.050000 56.930582
10.036209 4.053000 56.972753
9.976193 4.056000 57.014924
9.916266 4.059000 57.057095
9.856432 4.062000 57.099266
9.796692 4.065000 57.141436
9.737047 4.068000 57.183607
9.677498 4.071000 57.225778
9.618049 4.074000 57.267949
9.558700 4.077000 57.310120
9.499453 4.080000 57.352290
9.440310 4.083000 57.394461
9.381247 4.086000 57.436632
9.322222 4.089000 57.478803
9.263236 4.092000 57.520974
9.204291 4.095000 57.563144
9.145387 4.098000 57.605315
9.086522 4.101000 57.647486
9.027698 4.104000 57.689657
8.968915 4.107000 57.731828
8.910175 4.110000 57.773998
8.851479 4.113000 57.816169
8.792830 4.116000 57.858340
8.734227 4.119000 57.900511
8.675674 4.122000 57.942682
8.617170 4.125000 57.984852
8.558718 4.128000 58.027023
8.500320 4.131000 58.069194
8.441976 4.134000 58.111365
8.383689 4.137000 58.153536
8.325461 4.140000 58.195706
8.267292 4.143000 58.237877
8.209185 4.146000 58.280048
8.151141 4.149000 58.322219
8.093162 4.152000 58.364390
8.035251 4.155000 58.406560
7.977408 4.158000 58.448731
7.919637 4.161000 58.490902
7.861938 4.164000 58.533073
7.804313 4.167000 58.575244
7.746766 4.170000 58.617414
7.689297 4.173000 58.659585
7.631910 4.176000 58.701756
7.574605 4.179000 58.743927
7.517385 4.182000 58.786098
7.460253 4.185000 58.828269
7.403210 4.188000 58.870439
7.346260 4.191000 58.912610
7.289403 4.194000 58.954781
7.232643 4.197000 58.996952
7.175982 4.200000 59.039123
7.119422 4.203000 59.081293
7.062966 4.206000 59.123464
7.006616 4.209000 59.165635
6.950375 4.212000 59.207806
6.894246 4.215000 59.249977
6.838230 4.218000 59.292147
6.782331 4.221000 59.334318
6.726551 4.224000 59.376489
6.670893 4.227000 59.418660
6.615361 4.230000 59.460831
6.559955 4.233000 59.503001
6.504680 4.236000 59.545172
6.449538 4.239000 59.587343
6.394532 4.242000 59.629514
6.339666 4.245000 59.671685
6.284941 4.248000 59.713855
6.230361 4.251000 59.756026
6.175929 4.254000 59.798197
6.121648 4.257000 59.840368
6.067520 4.260000 59.882539
6.013550 4.263000 59.924709
5.959741 4.266000 59.966880
5.906094 4.269000 60.009051
5.852614 4.272000 60.051222
5.799304 4.275000 60.093393
5.746167 4.278000 60.135563
5.693206 4.281000 60.177734
5.640424 4.284000 60.219905
5.587824 4.287000 60.262076
5.535411 4.290000 60.304247
5.483187 4.293000 60.346417
5.431155 4.296000 60.388588
5.379319 4.299000 60.430759
5.327682 4.302000 60.472930
5.276247 4.305000 60.515101
5.225018 4.308000 60.557271
5.173998 4.311000 60.599442
5.123190 4.314000 60.641613
5.072598 4.317000 60.683784
5.022224 4.320000 60.725955
4.972073 4.323000 60.768125
4.922148 4.326000 60.810296
4.872451 4.329000 60.852467
4.822986 4.332000 60.894638
4.773756 4.335000 60.936809
4.724765 4.338000 60.978979
4.676015 4.341000 61.021150
4.627510 4.344000 61.063321
4.579253 4.347000 61.105492
4.531247 4.350000 61.147663
4.483495 4.353000 61.189833
4.436001 4.356000 61.232004
4.388766 4.359000 61.274175
4.341795 4.362000 61.316346
4.295089 4.365000 61.358517
4.248653 4.368000 61.400687
4.202488 4.371000 61.442858
4.156598 4.374000 61.485029
4.110985 4.377000 61.527200
4.065651 4.380000 61.569371
4.020601 4.383000 61.611541
3.975835 4.386000 61.653712
3.931357 4.389000 61.695883
3.887168 4.392000 61.738054
3.843272 4.395000 61.780225
3.799671 4.398000 61.822395
3.756366 4.401000 61.864566
3.713360 4.404000 61.906737
3.670655 4.407000 61.948908
3.628253 4.410000 61.991079
3.586155 4.413000 62.033249
3.544365 4.416000 62.075420
3.502882 4.419000 62.117591
3.461710 4.422000 62.159762
3.420850 4.425000 62.201933
3.380302 4.428000 62.244103
3.340069 4.431000 62.286274
3.300152 4.434000 62.328445
3.260552 4.437000 62.370616
3.221270 4.440000 62.412787
3.182307 4.443000 62.454957
3.143664 4.446000 62.497128
3.105342 4.449000 62.539299
3.067343 4.452000 62.581470
3.029665 4.455000 62.623641
2.992311 4.458000 62.665811
2.955280 4.461000 62.707982
2.918574 4.464000 62.750153
2.882191 4.467000 62.792324
2.846133 4.470000 62.834495
2.810400 4.473000 62.876665
2.774991 4.476000 62.918836
2.739907 4.479000 62.961007
2.705148 4.482000 63.003178
2.670712 4.485000 63.045349
2.636601 4.488000 63.087519
2.602813 4.491000 63.129690
2.569349 4.494000 63.171861
2.536207 4.497000 63.214032
2.503387 4.500000 63.256203
2.470888 4.503000 63.298373
2.438709 4.506000 63.340544
2.406850 4.509000 63.382715
2.375309 4.512000 63.424886
2.344086 4.515000 63.467057
2.313179 4.518000 63.509228
2.282587 4.521000 63.551398
2.252310 4.524000 63.593569
2.222344 4.527000 63.635740
2.192691 4.530000 63.677911
2.163347 4.533000 63.720082
2.134311 4.536000 63.762252
2.105582 4.539000 63.804423
2.077158 4.542000 63.846594
2.049038 4.545000 63.888765
2.021219 4.548000 63.930936
1.993700 4.551000 63.973106
1.966480 4.554000 64.015277
1.939555 4.557000 64.057448
1.912925 4.560000 64.099619
1.886587 4.563000 64.141790
1.860540 4.566000 64.183960
1.834780 4.569000 64.226131
1.809307 4.572000 64.268302
1.784118 4.575000 64.310473
1.759211 4.578000 64.352644
1.734583 4.581000 64.394814
1.710233 4.584000 64.436985
1.686158 4.587000 64.479156
1.662356 4.590000 64.521327
1.638824 4.593000 64.563498
1.615561 4.596000 64.605668
1.592563 4.599000 64.647839
1.569829 4.602000 64.690010
1.547357 4.605000 64.732181
1.525143 4.608000 64.774352
1.503185 4.611000 64.816522
1.481482 4.614000 64.858693
1.460029 4.617000 64.900864
1.438826 4.620000 64.943035
1.417869 4.623000 64.985206
1.397157 4.626000 65.027376
1.376686 4.629000 65.069547
1.356454 4.632000 65.111718
1.336459 4.635000 65.153889
1.316697 4.638000 65.196060
1.297168 4.641000 65.238230
1.277868 4.644000 65.280401
1.258794 4.647000 65.322572
1.239944 4.650000 65.364743
1.221316 4.653000 65.406914
1.202908 4.656000 65.449084
1.184716 4.659000 65.491255
1.166738 4.662000 65.533426
1.148973 4.665000 65.575597
1.131416 4.668000 65.617768
1.114067 4.671000 65.659938
1.096921 4.674000 65.702109
1.079978 4.677000 65.744280
1.063235 4.680000 65.786451
1.046689 4.683000 65.828622
1.030337 4.686000 65.870792
1.014178 4.689000 65.912963
0.998209 4.692000 65.955134
0.982428 4.695000 65.997305
0.966832 4.698000 66.039476
0.951420 4.701000 66.081646
0.936187 4.704000 66.123817
0.921134 4.707000 66.165988
0.906256 4.710000 66.208159
0.891552 4.713000 66.250330
0.877020 4.716000 66.292500
0.862657 4.719000 66.334671
0.848460 4.722000 66.376842
0.834429 4.725000 66.419013
0.820560 4.728000 66.461184
0.806852 4.731000 66.503354
0.793302 4.734000 66.545525
0.779908 4.737000 66.587696
0.766669 4.740000 66.629867
0.753581 4.743000 66.672038
0.740642 4.746000 66.714208
0.727852 4.749000 66.756379
0.715207 4.752000 66.798550
0.702706 4.755000 66.840721
0.690347 4.758000 66.882892
0.678127 4.761000 66.925062
0.666043 4.764000 66.967233
0.654063 4.767000 67.009404
0.642166 4.770000 67.051575
0.630352 4.773000 67.093746
0.618621 4.776000 67.135916
0.606971 4.779000 67.178087
0.595403 4.782000 67.220258
0.583916 4.785000 67.262429
0.572510 4.788000 67.304600
0.561184 4.791000 67.346770
0.549939 4.794000 67.388941
0.538760 4.797000 67.431112
0.527661 4.800000 67.473283
0.516640 4.803000 67.515454
0.505698 4.806000 67.557624
0.494834 4.809000 67.599795
0.484047 4.812000 67.641966
0.473338 4.815000 67.684137
0.462705 4.818000 67.726308
0.452149 4.821000 67.768478
0.441669 4.824000 67.810649
0.431263 4.827000 67.852820
0.420933 4.830000 67.894991
0.410677 4.833000 67.937162
0.400494 4.836000 67.979332
0.390383 4.839000 68.021503
0.380343 4.842000 68.063674
0.370372 4.845000 68.105845
0.360471 4.848000 68.148016
0.350637 4.851000 68.190187
0.340871 4.854000 68.232357
0.331171 4.857000 68.274528
0.321536 4.860000 68.316699
0.311965 4.863000 68.358870
0.302458 4.866000 68.401041
0.293014 4.869000 68.443211
0.283632 4.872000 68.485382
0.274310 4.875000 68.527553
0.265049 4.878000 68.569724
0.255846 4.881000 68.611895
0.246699 4.884000 68.654065
0.237609 4.887000 68.696236
0.228573 4.890000 68.738407
0.219589 4.893000 68.780578
0.210656 4.896000 68.822749
0.201771 4.899000 68.864919
0.192932 4.902000 68.907090
0.184137 4.905000 68.949261
0.175382 4.908000 68.991432
0.166665 4.911000 69.033603
0.157981 4.914000 69.075773
0.149327 4.917000 69.117944
0.140698 4.920000 69.160115
0.132087 4.923000 69.202286
0.123490 4.926000 69.244457
0.114897 4.929000 69.286627
0.106302 4.932000 69.328798
0.097692 4.935000 69.370969
0.089056 4.938000 69.413140
0.080377 4.941000 69.455311
0.071637 4.944000 69.497481
0.062811 4.947000 69.539652
0.053867 4.950000 69.581823
0.044765 4.953000 69.623994
0.035446 4.956000 69.666165
0.025835 4.959000 69.708335
0.015837 4.962000 69.750506
0.005426 4.965000 69.792677
0.001984 4.966000 69.806734

View File

@ -0,0 +1,554 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 80 MeV
80.000000 0.000000 0.000000
79.775385 0.016000 0.208857
79.550482 0.032000 0.417714
79.325289 0.048000 0.626571
79.099805 0.064000 0.835428
78.874029 0.080000 1.044285
78.647960 0.096000 1.253142
78.421596 0.112000 1.461999
78.194937 0.128000 1.670856
77.967981 0.144000 1.879713
77.740728 0.160000 2.088570
77.513175 0.176000 2.297427
77.285322 0.192000 2.506284
77.057167 0.208000 2.715141
76.828710 0.224000 2.923998
76.599949 0.240000 3.132855
76.370882 0.256000 3.341712
76.141509 0.272000 3.550569
75.911828 0.288000 3.759426
75.681838 0.304000 3.968283
75.451537 0.320000 4.177140
75.220926 0.336000 4.385997
74.990001 0.352000 4.594854
74.758762 0.368000 4.803711
74.527207 0.384000 5.012568
74.295335 0.400000 5.221425
74.063146 0.416000 5.430282
73.830636 0.432000 5.639139
73.597806 0.448000 5.847996
73.364653 0.464000 6.056853
73.131177 0.480000 6.265710
72.897376 0.496000 6.474567
72.663248 0.512000 6.683424
72.428792 0.528000 6.892281
72.194007 0.544000 7.101138
71.958891 0.560000 7.309995
71.723443 0.576000 7.518852
71.487661 0.592000 7.727709
71.251545 0.608000 7.936566
71.015091 0.624000 8.145423
70.778300 0.640000 8.354280
70.541169 0.656000 8.563137
70.303696 0.672000 8.771994
70.065882 0.688000 8.980851
69.827723 0.704000 9.189708
69.589218 0.720000 9.398565
69.350366 0.736000 9.607422
69.111165 0.752000 9.816279
68.871614 0.768000 10.025136
68.631711 0.784000 10.233993
68.391454 0.800000 10.442850
68.150842 0.816000 10.651707
67.909873 0.832000 10.860564
67.668545 0.848000 11.069421
67.426857 0.864000 11.278278
67.184807 0.880000 11.487135
66.942394 0.896000 11.695992
66.699615 0.912000 11.904849
66.456469 0.928000 12.113706
66.212955 0.944000 12.322563
65.969070 0.960000 12.531420
65.724812 0.976000 12.740277
65.480181 0.992000 12.949134
65.235173 1.008000 13.157991
64.989788 1.024000 13.366848
64.744023 1.040000 13.575705
64.497877 1.056000 13.784562
64.251348 1.072000 13.993419
64.004434 1.088000 14.202276
63.757132 1.104000 14.411133
63.509442 1.120000 14.619990
63.261361 1.136000 14.828847
63.012887 1.152000 15.037704
62.764018 1.168000 15.246561
62.514752 1.184000 15.455418
62.265088 1.200000 15.664275
62.015023 1.216000 15.873132
61.764555 1.232000 16.081989
61.513682 1.248000 16.290846
61.262402 1.264000 16.499703
61.010713 1.280000 16.708560
60.758613 1.296000 16.917417
60.506100 1.312000 17.126274
60.253171 1.328000 17.335131
59.999824 1.344000 17.543988
59.746057 1.360000 17.752845
59.491869 1.376000 17.961702
59.237256 1.392000 18.170559
58.982216 1.408000 18.379416
58.726748 1.424000 18.588273
58.470848 1.440000 18.797130
58.214514 1.456000 19.005987
57.957745 1.472000 19.214844
57.700537 1.488000 19.423701
57.442889 1.504000 19.632558
57.184797 1.520000 19.841415
56.926260 1.536000 20.050272
56.667275 1.552000 20.259129
56.407838 1.568000 20.467986
56.147949 1.584000 20.676843
55.887604 1.600000 20.885700
55.626800 1.616000 21.094557
55.365536 1.632000 21.303414
55.103807 1.648000 21.512271
54.841613 1.664000 21.721128
54.578949 1.680000 21.929985
54.315813 1.696000 22.138842
54.052203 1.712000 22.347699
53.788115 1.728000 22.556556
53.523547 1.744000 22.765413
53.258495 1.760000 22.974270
52.992958 1.776000 23.183127
52.726931 1.792000 23.391984
52.460412 1.808000 23.600841
52.193398 1.824000 23.809698
51.925886 1.840000 24.018555
51.657873 1.856000 24.227412
51.389355 1.872000 24.436269
51.120329 1.888000 24.645126
50.850793 1.904000 24.853983
50.580742 1.920000 25.062840
50.310174 1.936000 25.271697
50.039085 1.952000 25.480554
49.767472 1.968000 25.689411
49.495331 1.984000 25.898268
49.222659 2.000000 26.107125
48.949452 2.016000 26.315982
48.675707 2.032000 26.524839
48.401420 2.048000 26.733696
48.126587 2.064000 26.942553
47.851205 2.080000 27.151410
47.575269 2.096000 27.360267
47.298776 2.112000 27.569124
47.021723 2.128000 27.777981
46.744104 2.144000 27.986838
46.465916 2.160000 28.195695
46.187155 2.176000 28.404552
45.907817 2.192000 28.613409
45.627897 2.208000 28.822266
45.347391 2.224000 29.031123
45.066294 2.240000 29.239980
44.784603 2.256000 29.448837
44.502313 2.272000 29.657694
44.219419 2.288000 29.866551
43.935916 2.304000 30.075408
43.651800 2.320000 30.284265
43.367065 2.336000 30.493122
43.081708 2.352000 30.701979
42.795722 2.368000 30.910836
42.509103 2.384000 31.119693
42.221845 2.400000 31.328550
41.933943 2.416000 31.537407
41.645393 2.432000 31.746264
41.356187 2.448000 31.955121
41.066321 2.464000 32.163978
40.775788 2.480000 32.372835
40.484584 2.496000 32.581692
40.192701 2.512000 32.790549
39.900135 2.528000 32.999406
39.606878 2.544000 33.208263
39.312924 2.560000 33.417120
39.018266 2.576000 33.625977
38.722899 2.592000 33.834834
38.426815 2.608000 34.043691
38.130007 2.624000 34.252548
37.832468 2.640000 34.461405
37.534191 2.656000 34.670262
37.235168 2.672000 34.879119
36.935391 2.688000 35.087976
36.634853 2.704000 35.296833
36.333546 2.720000 35.505690
36.031461 2.736000 35.714547
35.728590 2.752000 35.923404
35.424924 2.768000 36.132261
35.120454 2.784000 36.341118
34.815171 2.800000 36.549975
34.509065 2.816000 36.758832
34.202127 2.832000 36.967689
33.894347 2.848000 37.176546
33.585714 2.864000 37.385403
33.276217 2.880000 37.594260
32.965847 2.896000 37.803117
32.654590 2.912000 38.011974
32.342437 2.928000 38.220831
32.029374 2.944000 38.429688
31.715389 2.960000 38.638545
31.400470 2.976000 38.847402
31.084739 2.992000 39.056259
30.768292 3.008000 39.265116
30.451131 3.024000 39.473973
30.133253 3.040000 39.682830
29.814656 3.056000 39.891687
29.495335 3.072000 40.100544
29.175288 3.088000 40.309401
28.854512 3.104000 40.518258
28.533004 3.120000 40.727115
28.210761 3.136000 40.935972
27.887780 3.152000 41.144829
27.564059 3.168000 41.353686
27.239594 3.184000 41.562543
26.914383 3.200000 41.771400
26.588424 3.216000 41.980257
26.261713 3.232000 42.189114
25.934249 3.248000 42.397971
25.606028 3.264000 42.606828
25.277049 3.280000 42.815685
24.947309 3.296000 43.024542
24.616806 3.312000 43.233399
24.285538 3.328000 43.442256
23.953504 3.344000 43.651113
23.620701 3.360000 43.859970
23.287128 3.376000 44.068827
22.952783 3.392000 44.277684
22.617667 3.408000 44.486541
22.281776 3.424000 44.695398
21.945112 3.440000 44.904255
21.607674 3.456000 45.113112
21.269462 3.472000 45.321969
20.930476 3.488000 45.530826
20.590717 3.504000 45.739683
20.250186 3.520000 45.948540
19.908886 3.536000 46.157397
19.566818 3.552000 46.366254
19.223987 3.568000 46.575111
18.880396 3.584000 46.783968
18.536051 3.600000 46.992825
18.191294 3.616000 47.201682
17.846475 3.632000 47.410540
17.501642 3.648000 47.619397
17.156838 3.664000 47.828254
16.812108 3.680000 48.037111
16.467500 3.696000 48.245968
16.123065 3.712000 48.454825
15.778861 3.728000 48.663682
15.434946 3.744000 48.872539
15.091386 3.760000 49.081396
14.748251 3.776000 49.290253
14.405618 3.792000 49.499110
14.063569 3.808000 49.707967
13.722193 3.824000 49.916824
13.381587 3.840000 50.125681
13.041857 3.856000 50.334538
12.703117 3.872000 50.543395
12.365491 3.888000 50.752252
12.029116 3.904000 50.961109
11.694137 3.920000 51.169966
11.360715 3.936000 51.378823
11.029024 3.952000 51.587680
10.699253 3.968000 51.796537
10.371606 3.984000 52.005394
10.046304 4.000000 52.214251
9.985590 4.003000 52.253411
9.924968 4.006000 52.292572
9.864441 4.009000 52.331733
9.804009 4.012000 52.370893
9.743675 4.015000 52.410054
9.683441 4.018000 52.449215
9.623307 4.021000 52.488375
9.563276 4.024000 52.527536
9.503349 4.027000 52.566697
9.443529 4.030000 52.605857
9.383795 4.033000 52.645018
9.324101 4.036000 52.684179
9.264450 4.039000 52.723339
9.204842 4.042000 52.762500
9.145277 4.045000 52.801661
9.085753 4.048000 52.840822
9.026270 4.051000 52.879982
8.966830 4.054000 52.919143
8.907435 4.057000 52.958304
8.848085 4.060000 52.997464
8.788783 4.063000 53.036625
8.729529 4.066000 53.075786
8.670325 4.069000 53.114946
8.611174 4.072000 53.154107
8.552076 4.075000 53.193268
8.493033 4.078000 53.232428
8.434046 4.081000 53.271589
8.375118 4.084000 53.310750
8.316250 4.087000 53.349911
8.257444 4.090000 53.389071
8.198701 4.093000 53.428232
8.140024 4.096000 53.467393
8.081414 4.099000 53.506553
8.022874 4.102000 53.545714
7.964404 4.105000 53.584875
7.906008 4.108000 53.624035
7.847687 4.111000 53.663196
7.789443 4.114000 53.702357
7.731278 4.117000 53.741517
7.673195 4.120000 53.780678
7.615195 4.123000 53.819839
7.557281 4.126000 53.858999
7.499455 4.129000 53.898160
7.441719 4.132000 53.937321
7.384076 4.135000 53.976482
7.326527 4.138000 54.015642
7.269076 4.141000 54.054803
7.211725 4.144000 54.093964
7.154476 4.147000 54.133124
7.097331 4.150000 54.172285
7.040294 4.153000 54.211446
6.983367 4.156000 54.250606
6.926552 4.159000 54.289767
6.869852 4.162000 54.328928
6.813270 4.165000 54.368088
6.756808 4.168000 54.407249
6.700470 4.171000 54.446410
6.644258 4.174000 54.485570
6.588175 4.177000 54.524731
6.532224 4.180000 54.563892
6.476408 4.183000 54.603053
6.420729 4.186000 54.642213
6.365191 4.189000 54.681374
6.309797 4.192000 54.720535
6.254549 4.195000 54.759695
6.199452 4.198000 54.798856
6.144507 4.201000 54.838017
6.089718 4.204000 54.877177
6.035089 4.207000 54.916338
5.980622 4.210000 54.955499
5.926321 4.213000 54.994659
5.872189 4.216000 55.033820
5.818229 4.219000 55.072981
5.764444 4.222000 55.112141
5.710839 4.225000 55.151302
5.657415 4.228000 55.190463
5.604177 4.231000 55.229624
5.551128 4.234000 55.268784
5.498270 4.237000 55.307945
5.445609 4.240000 55.347106
5.393146 4.243000 55.386266
5.340886 4.246000 55.425427
5.288832 4.249000 55.464588
5.236986 4.252000 55.503748
5.185354 4.255000 55.542909
5.133937 4.258000 55.582070
5.082740 4.261000 55.621230
5.031765 4.264000 55.660391
4.981017 4.267000 55.699552
4.930499 4.270000 55.738712
4.880213 4.273000 55.777873
4.830164 4.276000 55.817034
4.780354 4.279000 55.856195
4.730787 4.282000 55.895355
4.681467 4.285000 55.934516
4.632396 4.288000 55.973677
4.583578 4.291000 56.012837
4.535016 4.294000 56.051998
4.486713 4.297000 56.091159
4.438672 4.300000 56.130319
4.390896 4.303000 56.169480
4.343389 4.306000 56.208641
4.296154 4.309000 56.247801
4.249193 4.312000 56.286962
4.202509 4.315000 56.326123
4.156105 4.318000 56.365283
4.109984 4.321000 56.404444
4.064149 4.324000 56.443605
4.018602 4.327000 56.482766
3.973347 4.330000 56.521926
3.928385 4.333000 56.561087
3.883718 4.336000 56.600248
3.839351 4.339000 56.639408
3.795284 4.342000 56.678569
3.751520 4.345000 56.717730
3.708062 4.348000 56.756890
3.664911 4.351000 56.796051
3.622069 4.354000 56.835212
3.579539 4.357000 56.874372
3.537322 4.360000 56.913533
3.495421 4.363000 56.952694
3.453836 4.366000 56.991854
3.412569 4.369000 57.031015
3.371622 4.372000 57.070176
3.330997 4.375000 57.109337
3.290694 4.378000 57.148497
3.250715 4.381000 57.187658
3.211061 4.384000 57.226819
3.171733 4.387000 57.265979
3.132733 4.390000 57.305140
3.094060 4.393000 57.344301
3.055716 4.396000 57.383461
3.017702 4.399000 57.422622
2.980017 4.402000 57.461783
2.942664 4.405000 57.500943
2.905641 4.408000 57.540104
2.868949 4.411000 57.579265
2.832589 4.414000 57.618425
2.796560 4.417000 57.657586
2.760862 4.420000 57.696747
2.725497 4.423000 57.735908
2.690462 4.426000 57.775068
2.655759 4.429000 57.814229
2.621386 4.432000 57.853390
2.587344 4.435000 57.892550
2.553631 4.438000 57.931711
2.520247 4.441000 57.970872
2.487192 4.444000 58.010032
2.454465 4.447000 58.049193
2.422064 4.450000 58.088354
2.389990 4.453000 58.127514
2.358240 4.456000 58.166675
2.326814 4.459000 58.205836
2.295710 4.462000 58.244996
2.264928 4.465000 58.284157
2.234466 4.468000 58.323318
2.204322 4.471000 58.362479
2.174496 4.474000 58.401639
2.144986 4.477000 58.440800
2.115789 4.480000 58.479961
2.086905 4.483000 58.519121
2.058332 4.486000 58.558282
2.030068 4.489000 58.597443
2.002111 4.492000 58.636603
1.974459 4.495000 58.675764
1.947110 4.498000 58.714925
1.920063 4.501000 58.754085
1.893316 4.504000 58.793246
1.866866 4.507000 58.832407
1.840711 4.510000 58.871567
1.814849 4.513000 58.910728
1.789278 4.516000 58.949889
1.763996 4.519000 58.989050
1.739001 4.522000 59.028210
1.714289 4.525000 59.067371
1.689860 4.528000 59.106532
1.665710 4.531000 59.145692
1.641837 4.534000 59.184853
1.618239 4.537000 59.224014
1.594913 4.540000 59.263174
1.571857 4.543000 59.302335
1.549069 4.546000 59.341496
1.526545 4.549000 59.380656
1.504284 4.552000 59.419817
1.482283 4.555000 59.458978
1.460540 4.558000 59.498139
1.439051 4.561000 59.537299
1.417815 4.564000 59.576460
1.396829 4.567000 59.615621
1.376090 4.570000 59.654781
1.355596 4.573000 59.693942
1.335343 4.576000 59.733103
1.315331 4.579000 59.772263
1.295555 4.582000 59.811424
1.276014 4.585000 59.850585
1.256705 4.588000 59.889745
1.237625 4.591000 59.928906
1.218772 4.594000 59.968067
1.200143 4.597000 60.007227
1.181736 4.600000 60.046388
1.163547 4.603000 60.085549
1.145576 4.606000 60.124710
1.127818 4.609000 60.163870
1.110272 4.612000 60.203031
1.092935 4.615000 60.242192
1.075804 4.618000 60.281352
1.058877 4.621000 60.320513
1.042152 4.624000 60.359674
1.025625 4.627000 60.398834
1.009296 4.630000 60.437995
0.993160 4.633000 60.477156
0.977216 4.636000 60.516316
0.961461 4.639000 60.555477
0.945893 4.642000 60.594638
0.930509 4.645000 60.633798
0.915307 4.648000 60.672959
0.900285 4.651000 60.712120
0.885441 4.654000 60.751281
0.870771 4.657000 60.790441
0.856273 4.660000 60.829602
0.841946 4.663000 60.868763
0.827786 4.666000 60.907923
0.813793 4.669000 60.947084
0.799963 4.672000 60.986245
0.786295 4.675000 61.025405
0.772785 4.678000 61.064566
0.759432 4.681000 61.103727
0.746234 4.684000 61.142887
0.733188 4.687000 61.182048
0.720293 4.690000 61.221209
0.707546 4.693000 61.260369
0.694945 4.696000 61.299530
0.682488 4.699000 61.338691
0.670173 4.702000 61.377852
0.657981 4.705000 61.417012
0.645878 4.708000 61.456173
0.633862 4.711000 61.495334
0.621931 4.714000 61.534494
0.610087 4.717000 61.573655
0.598328 4.720000 61.612816
0.586655 4.723000 61.651976
0.575065 4.726000 61.691137
0.563560 4.729000 61.730298
0.552139 4.732000 61.769458
0.540788 4.735000 61.808619
0.529519 4.738000 61.847780
0.518333 4.741000 61.886940
0.507229 4.744000 61.926101
0.496206 4.747000 61.965262
0.485263 4.750000 62.004423
0.474402 4.753000 62.043583
0.463620 4.756000 62.082744
0.452917 4.759000 62.121905
0.442293 4.762000 62.161065
0.431747 4.765000 62.200226
0.421278 4.768000 62.239387
0.410887 4.771000 62.278547
0.400572 4.774000 62.317708
0.390331 4.777000 62.356869
0.380162 4.780000 62.396029
0.370065 4.783000 62.435190
0.360039 4.786000 62.474351
0.350083 4.789000 62.513511
0.340195 4.792000 62.552672
0.330374 4.795000 62.591833
0.320620 4.798000 62.630994
0.310931 4.801000 62.670154
0.301307 4.804000 62.709315
0.291748 4.807000 62.748476
0.282251 4.810000 62.787636
0.272816 4.813000 62.826797
0.263441 4.816000 62.865958
0.254127 4.819000 62.905118
0.244870 4.822000 62.944279
0.235669 4.825000 62.983440
0.226524 4.828000 63.022600
0.217431 4.831000 63.061761
0.208390 4.834000 63.100922
0.199397 4.837000 63.140082
0.190450 4.840000 63.179243
0.181547 4.843000 63.218404
0.172685 4.846000 63.257565
0.163859 4.849000 63.296725
0.155067 4.852000 63.335886
0.146302 4.855000 63.375047
0.137561 4.858000 63.414207
0.128837 4.861000 63.453368
0.120124 4.864000 63.492529
0.111412 4.867000 63.531689
0.102693 4.870000 63.570850
0.093954 4.873000 63.610011
0.085181 4.876000 63.649171
0.076358 4.879000 63.688332
0.067460 4.882000 63.727493
0.058461 4.885000 63.766653
0.049323 4.888000 63.805814
0.039996 4.891000 63.844975
0.030414 4.894000 63.884136
0.020486 4.897000 63.923296
0.010125 4.900000 63.962457
0.000000 4.903000 64.001618

View File

@ -0,0 +1,326 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 80 MeV
80.000000 0.000000 0.000000
79.688803 0.020000 0.200813
79.377050 0.040000 0.401627
79.064738 0.060000 0.602440
78.751864 0.080000 0.803253
78.438424 0.100000 1.004067
78.124416 0.120000 1.204880
77.809837 0.140000 1.405693
77.494682 0.160000 1.606507
77.178950 0.180000 1.807320
76.862636 0.200000 2.008133
76.545737 0.220000 2.208947
76.228251 0.240000 2.409760
75.910173 0.260000 2.610573
75.591501 0.280000 2.811387
75.272230 0.300000 3.012200
74.952358 0.320000 3.213013
74.631881 0.340000 3.413827
74.310794 0.360000 3.614640
73.989096 0.380000 3.815453
73.666782 0.400000 4.016267
73.343848 0.420000 4.217080
73.020291 0.440000 4.417894
72.696107 0.460000 4.618707
72.371292 0.480000 4.819520
72.045843 0.500000 5.020334
71.719756 0.520000 5.221147
71.393026 0.540000 5.421960
71.065650 0.560000 5.622774
70.737624 0.580000 5.823587
70.408943 0.600000 6.024400
70.079604 0.620000 6.225214
69.749604 0.640000 6.426027
69.418936 0.660000 6.626840
69.087598 0.680000 6.827654
68.755585 0.700000 7.028467
68.422892 0.720000 7.229280
68.089516 0.740000 7.430094
67.755452 0.760000 7.630907
67.420696 0.780000 7.831720
67.085243 0.800000 8.032534
66.749088 0.820000 8.233347
66.412227 0.840000 8.434160
66.074656 0.860000 8.634974
65.736369 0.880000 8.835787
65.397362 0.900000 9.036600
65.057630 0.920000 9.237414
64.717168 0.940000 9.438227
64.375971 0.960000 9.639040
64.034035 0.980000 9.839854
63.691353 1.000000 10.040667
63.347922 1.020000 10.241480
63.003735 1.040000 10.442294
62.658787 1.060000 10.643107
62.313074 1.080000 10.843920
61.966590 1.100000 11.044734
61.619329 1.120000 11.245547
61.271286 1.140000 11.446360
60.922455 1.160000 11.647174
60.572830 1.180000 11.847987
60.222406 1.200000 12.048801
59.871177 1.220000 12.249614
59.519137 1.240000 12.450427
59.166280 1.260000 12.651241
58.812599 1.280000 12.852054
58.458090 1.300000 13.052867
58.102744 1.320000 13.253681
57.746557 1.340000 13.454494
57.389521 1.360000 13.655307
57.031631 1.380000 13.856121
56.672878 1.400000 14.056934
56.313258 1.420000 14.257747
55.952762 1.440000 14.458561
55.591384 1.460000 14.659374
55.229117 1.480000 14.860187
54.865953 1.500000 15.061001
54.501886 1.520000 15.261814
54.136907 1.540000 15.462627
53.771010 1.560000 15.663441
53.404187 1.580000 15.864254
53.036430 1.600000 16.065067
52.667731 1.620000 16.265881
52.298082 1.640000 16.466694
51.927475 1.660000 16.667507
51.555901 1.680000 16.868321
51.183352 1.700000 17.069134
50.809820 1.720000 17.269947
50.435296 1.740000 17.470761
50.059770 1.760000 17.671574
49.683234 1.780000 17.872387
49.305678 1.800000 18.073201
48.927093 1.820000 18.274014
48.547470 1.840000 18.474827
48.166797 1.860000 18.675641
47.785067 1.880000 18.876454
47.402267 1.900000 19.077267
47.018388 1.920000 19.278081
46.633419 1.940000 19.478894
46.247348 1.960000 19.679708
45.860166 1.980000 19.880521
45.471861 2.000000 20.081334
45.082420 2.020000 20.282148
44.691832 2.040000 20.482961
44.300085 2.060000 20.683774
43.907166 2.080000 20.884588
43.513062 2.100000 21.085401
43.117761 2.120000 21.286214
42.721249 2.140000 21.487028
42.323512 2.160000 21.687841
41.924536 2.180000 21.888654
41.524306 2.200000 22.089468
41.122807 2.220000 22.290281
40.720025 2.240000 22.491094
40.315943 2.260000 22.691908
39.910545 2.280000 22.892721
39.503814 2.300000 23.093534
39.095734 2.320000 23.294348
38.686285 2.340000 23.495161
38.275451 2.360000 23.695974
37.863212 2.380000 23.896788
37.449548 2.400000 24.097601
37.034440 2.420000 24.298414
36.617866 2.440000 24.499228
36.199805 2.460000 24.700041
35.780234 2.480000 24.900854
35.359130 2.500000 25.101668
34.936469 2.520000 25.302481
34.512226 2.540000 25.503294
34.086374 2.560000 25.704108
33.658887 2.580000 25.904921
33.229737 2.600000 26.105734
32.798893 2.620000 26.306548
32.366325 2.640000 26.507361
31.932000 2.660000 26.708174
31.495886 2.680000 26.908988
31.058108 2.700000 27.109801
30.618942 2.720000 27.310614
30.178391 2.740000 27.511428
29.736448 2.760000 27.712241
29.293103 2.780000 27.913055
28.848348 2.800000 28.113868
28.402175 2.820000 28.314681
27.954576 2.840000 28.515495
27.505544 2.860000 28.716308
27.055071 2.880000 28.917121
26.603148 2.900000 29.117935
26.149770 2.920000 29.318748
25.694928 2.940000 29.519561
25.238617 2.960000 29.720375
24.780830 2.980000 29.921188
24.321560 3.000000 30.122001
23.860803 3.020000 30.322815
23.398554 3.040000 30.523628
22.934808 3.060000 30.724441
22.469563 3.080000 30.925255
22.002814 3.100000 31.126068
21.534561 3.120000 31.326881
21.064804 3.140000 31.527695
20.593543 3.160000 31.728508
20.120781 3.180000 31.929321
19.646523 3.200000 32.130135
19.170777 3.220000 32.330948
18.693552 3.240000 32.531761
18.215161 3.260000 32.732575
17.736573 3.280000 32.933388
17.257970 3.300000 33.134201
16.779470 3.320000 33.335015
16.301199 3.340000 33.535828
15.823299 3.360000 33.736641
15.345927 3.380000 33.937455
14.869258 3.400000 34.138268
14.393487 3.420000 34.339081
13.918832 3.440000 34.539895
13.445535 3.460000 34.740708
12.973871 3.480000 34.941521
12.504146 3.500000 35.142335
12.036705 3.520000 35.343148
11.571935 3.540000 35.543962
11.110272 3.560000 35.744775
10.652203 3.580000 35.945588
10.198276 3.600000 36.146402
9.749100 3.620000 36.347215
9.305192 3.640000 36.548028
8.864425 3.660000 36.748842
8.426224 3.680000 36.949655
7.991228 3.700000 37.150468
7.560188 3.720000 37.351282
7.133965 3.740000 37.552095
6.713536 3.760000 37.752908
6.299994 3.780000 37.953722
5.894542 3.800000 38.154535
5.498474 3.820000 38.355348
5.113148 3.840000 38.556162
4.739951 3.860000 38.756975
4.380247 3.880000 38.957788
4.035323 3.900000 39.158602
3.706328 3.920000 39.359415
3.394217 3.940000 39.560228
3.099704 3.960000 39.761042
2.823232 3.980000 39.961855
2.564958 4.000000 40.162668
2.324760 4.020000 40.363482
2.102259 4.040000 40.564295
1.896859 4.060000 40.765108
1.867478 4.063000 40.795230
1.838462 4.066000 40.825352
1.809808 4.069000 40.855474
1.781512 4.072000 40.885596
1.753572 4.075000 40.915718
1.725985 4.078000 40.945840
1.698747 4.081000 40.975962
1.671855 4.084000 41.006084
1.645306 4.087000 41.036206
1.619097 4.090000 41.066328
1.593224 4.093000 41.096450
1.567684 4.096000 41.126572
1.542474 4.099000 41.156694
1.517589 4.102000 41.186816
1.493028 4.105000 41.216938
1.468785 4.108000 41.247060
1.444859 4.111000 41.277182
1.421244 4.114000 41.307304
1.397939 4.117000 41.337426
1.374939 4.120000 41.367548
1.352240 4.123000 41.397670
1.329840 4.126000 41.427792
1.307734 4.129000 41.457914
1.285919 4.132000 41.488036
1.264393 4.135000 41.518158
1.243150 4.138000 41.548280
1.222187 4.141000 41.578402
1.201502 4.144000 41.608524
1.181090 4.147000 41.638646
1.160949 4.150000 41.668768
1.141073 4.153000 41.698890
1.121461 4.156000 41.729012
1.102109 4.159000 41.759134
1.083012 4.162000 41.789256
1.064168 4.165000 41.819378
1.045574 4.168000 41.849500
1.027225 4.171000 41.879622
1.009119 4.174000 41.909744
0.991252 4.177000 41.939866
0.973621 4.180000 41.969988
0.956222 4.183000 42.000110
0.939052 4.186000 42.030232
0.922108 4.189000 42.060354
0.905387 4.192000 42.090476
0.888885 4.195000 42.120598
0.872600 4.198000 42.150720
0.856527 4.201000 42.180842
0.840663 4.204000 42.210964
0.825007 4.207000 42.241086
0.809554 4.210000 42.271208
0.794301 4.213000 42.301330
0.779247 4.216000 42.331452
0.764386 4.219000 42.361574
0.749717 4.222000 42.391696
0.735236 4.225000 42.421818
0.720941 4.228000 42.451940
0.706828 4.231000 42.482062
0.692895 4.234000 42.512184
0.679139 4.237000 42.542306
0.665555 4.240000 42.572428
0.652102 4.243000 42.602550
0.638755 4.246000 42.632672
0.625511 4.249000 42.662794
0.612371 4.252000 42.692916
0.599334 4.255000 42.723038
0.586400 4.258000 42.753160
0.573569 4.261000 42.783282
0.560839 4.264000 42.813404
0.548205 4.267000 42.843526
0.535662 4.270000 42.873648
0.523219 4.273000 42.903770
0.510875 4.276000 42.933892
0.498630 4.279000 42.964014
0.486484 4.282000 42.994136
0.474435 4.285000 43.024258
0.462483 4.288000 43.054381
0.450627 4.291000 43.084503
0.438867 4.294000 43.114625
0.427202 4.297000 43.144747
0.415631 4.300000 43.174869
0.404153 4.303000 43.204991
0.392767 4.306000 43.235113
0.381471 4.309000 43.265235
0.370262 4.312000 43.295357
0.359141 4.315000 43.325479
0.348106 4.318000 43.355601
0.337155 4.321000 43.385723
0.326286 4.324000 43.415845
0.315500 4.327000 43.445967
0.304795 4.330000 43.476089
0.294169 4.333000 43.506211
0.283622 4.336000 43.536333
0.273151 4.339000 43.566455
0.262756 4.342000 43.596577
0.252434 4.345000 43.626699
0.242183 4.348000 43.656821
0.232002 4.351000 43.686943
0.221888 4.354000 43.717065
0.211839 4.357000 43.747187
0.201851 4.360000 43.777309
0.191922 4.363000 43.807431
0.182047 4.366000 43.837553
0.172222 4.369000 43.867675
0.162443 4.372000 43.897797
0.152704 4.375000 43.927919
0.142999 4.378000 43.958041
0.133320 4.381000 43.988163
0.123659 4.384000 44.018285
0.114004 4.387000 44.048407
0.104345 4.390000 44.078529
0.094664 4.393000 44.108651
0.084944 4.396000 44.138773
0.075160 4.399000 44.168895
0.065281 4.402000 44.199017
0.055267 4.405000 44.229139
0.045062 4.408000 44.259261
0.034588 4.411000 44.289383
0.023738 4.414000 44.319505
0.012376 4.417000 44.349627
0.000722 4.420000 44.379749

View File

@ -0,0 +1,275 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 80 MeV
80.000000 0.000000 0.000000
79.652863 0.022000 0.205127
79.305036 0.044000 0.410255
78.956514 0.066000 0.615382
78.607294 0.088000 0.820510
78.257370 0.110000 1.025637
77.906739 0.132000 1.230764
77.555397 0.154000 1.435892
77.203338 0.176000 1.641019
76.850558 0.198000 1.846147
76.497053 0.220000 2.051274
76.142818 0.242000 2.256402
75.787848 0.264000 2.461529
75.432139 0.286000 2.666656
75.075687 0.308000 2.871784
74.718485 0.330000 3.076911
74.360529 0.352000 3.282039
74.001815 0.374000 3.487166
73.642337 0.396000 3.692293
73.282091 0.418000 3.897421
72.921071 0.440000 4.102548
72.559271 0.462000 4.307676
72.196688 0.484000 4.512803
71.833315 0.506000 4.717930
71.469148 0.528000 4.923058
71.104181 0.550000 5.128185
70.738407 0.572000 5.333313
70.371823 0.594000 5.538440
70.004422 0.616000 5.743568
69.636199 0.638000 5.948695
69.267147 0.660000 6.153822
68.897262 0.682000 6.358950
68.526536 0.704000 6.564077
68.154965 0.726000 6.769205
67.782542 0.748000 6.974332
67.409261 0.770000 7.179459
67.035116 0.792000 7.384587
66.660101 0.814000 7.589714
66.284209 0.836000 7.794842
65.907434 0.858000 7.999969
65.529769 0.880000 8.205097
65.151207 0.902000 8.410224
64.771743 0.924000 8.615351
64.391369 0.946000 8.820479
64.010078 0.968000 9.025606
63.627864 0.990000 9.230734
63.244719 1.012000 9.435861
62.860636 1.034000 9.640988
62.475608 1.056000 9.846116
62.089627 1.078000 10.051243
61.702686 1.100000 10.256371
61.314778 1.122000 10.461498
60.925894 1.144000 10.666625
60.536028 1.166000 10.871753
60.145170 1.188000 11.076880
59.753313 1.210000 11.282008
59.360448 1.232000 11.487135
58.966568 1.254000 11.692263
58.571664 1.276000 11.897390
58.175727 1.298000 12.102517
57.778749 1.320000 12.307645
57.380720 1.342000 12.512772
56.981633 1.364000 12.717900
56.581477 1.386000 12.923027
56.180243 1.408000 13.128154
55.777922 1.430000 13.333282
55.374504 1.452000 13.538409
54.969980 1.474000 13.743537
54.564339 1.496000 13.948664
54.157572 1.518000 14.153791
53.749667 1.540000 14.358919
53.340616 1.562000 14.564046
52.930406 1.584000 14.769174
52.519026 1.606000 14.974301
52.106467 1.628000 15.179429
51.692716 1.650000 15.384556
51.277762 1.672000 15.589683
50.861594 1.694000 15.794811
50.444198 1.716000 15.999938
50.025563 1.738000 16.205066
49.605677 1.760000 16.410193
49.184526 1.782000 16.615320
48.762097 1.804000 16.820448
48.338378 1.826000 17.025575
47.913354 1.848000 17.230703
47.487012 1.870000 17.435830
47.059337 1.892000 17.640958
46.630315 1.914000 17.846085
46.199931 1.936000 18.051212
45.768168 1.958000 18.256340
45.335013 1.980000 18.461467
44.900448 2.002000 18.666595
44.464457 2.024000 18.871722
44.027023 2.046000 19.076849
43.588129 2.068000 19.281977
43.147757 2.090000 19.487104
42.705888 2.112000 19.692232
42.262504 2.134000 19.897359
41.817584 2.156000 20.102486
41.371110 2.178000 20.307614
40.923060 2.200000 20.512741
40.473413 2.222000 20.717869
40.022147 2.244000 20.922996
39.569239 2.266000 21.128124
39.114666 2.288000 21.333251
38.658404 2.310000 21.538378
38.200427 2.332000 21.743506
37.740710 2.354000 21.948633
37.279224 2.376000 22.153761
36.815944 2.398000 22.358888
36.350838 2.420000 22.564015
35.883878 2.442000 22.769143
35.415030 2.464000 22.974270
34.944264 2.486000 23.179398
34.471544 2.508000 23.384525
33.996834 2.530000 23.589652
33.520097 2.552000 23.794780
33.041294 2.574000 23.999907
32.560384 2.596000 24.205035
32.077324 2.618000 24.410162
31.592067 2.640000 24.615290
31.104689 2.662000 24.820417
30.615570 2.684000 25.025544
30.124743 2.706000 25.230672
29.632198 2.728000 25.435799
29.137922 2.750000 25.640927
28.641906 2.772000 25.846054
28.144138 2.794000 26.051181
27.644608 2.816000 26.256309
27.143305 2.838000 26.461436
26.640219 2.860000 26.666564
26.135342 2.882000 26.871691
25.628663 2.904000 27.076819
25.120174 2.926000 27.281946
24.609866 2.948000 27.487073
24.097733 2.970000 27.692201
23.583768 2.992000 27.897328
23.067964 3.014000 28.102456
22.550318 3.036000 28.307583
22.030825 3.058000 28.512710
21.509485 3.080000 28.717838
20.986298 3.102000 28.922965
20.461265 3.124000 29.128093
19.934392 3.146000 29.333220
19.405688 3.168000 29.538347
18.875166 3.190000 29.743475
18.342952 3.212000 29.948602
17.810238 3.234000 30.153730
17.277504 3.256000 30.358857
16.744907 3.278000 30.563985
16.212626 3.300000 30.769112
15.680858 3.322000 30.974239
15.149825 3.344000 31.179367
14.619780 3.366000 31.384494
14.091004 3.388000 31.589622
13.563818 3.410000 31.794749
13.038586 3.432000 31.999876
12.515722 3.454000 32.205004
11.995696 3.476000 32.410131
11.479043 3.498000 32.615259
10.966373 3.520000 32.820386
10.458376 3.542000 33.025513
9.955836 3.564000 33.230641
9.459634 3.586000 33.435768
8.968587 3.608000 33.640896
8.480624 3.630000 33.846023
7.996543 3.652000 34.051151
7.517365 3.674000 34.256278
7.044277 3.696000 34.461405
6.578645 3.718000 34.666533
6.122008 3.740000 34.871660
5.676063 3.762000 35.076788
5.242633 3.784000 35.281915
4.823608 3.806000 35.487042
4.420872 3.828000 35.692170
4.036211 3.850000 35.897297
3.671213 3.872000 36.102425
3.327175 3.894000 36.307552
3.005018 3.916000 36.512679
2.705246 3.938000 36.717807
2.427930 3.960000 36.922934
2.172726 3.982000 37.128062
1.938931 4.004000 37.333189
1.898649 4.008000 37.370485
1.859036 4.012000 37.407781
1.820084 4.016000 37.445077
1.781787 4.020000 37.482373
1.744136 4.024000 37.519669
1.707124 4.028000 37.556965
1.670744 4.032000 37.594260
1.634987 4.036000 37.631556
1.599846 4.040000 37.668852
1.565312 4.044000 37.706148
1.531376 4.048000 37.743444
1.498031 4.052000 37.780740
1.465269 4.056000 37.818036
1.433080 4.060000 37.855332
1.401456 4.064000 37.892628
1.370389 4.068000 37.929923
1.339869 4.072000 37.967219
1.309889 4.076000 38.004515
1.280440 4.080000 38.041811
1.251512 4.084000 38.079107
1.223098 4.088000 38.116403
1.195189 4.092000 38.153699
1.167776 4.096000 38.190995
1.140850 4.100000 38.228291
1.114403 4.104000 38.265586
1.088427 4.108000 38.302882
1.062913 4.112000 38.340178
1.037853 4.116000 38.377474
1.013238 4.120000 38.414770
0.989061 4.124000 38.452066
0.965312 4.128000 38.489362
0.941984 4.132000 38.526658
0.919069 4.136000 38.563954
0.896559 4.140000 38.601250
0.874445 4.144000 38.638545
0.852720 4.148000 38.675841
0.831375 4.152000 38.713137
0.810405 4.156000 38.750433
0.789800 4.160000 38.787729
0.769555 4.164000 38.825025
0.749659 4.168000 38.862321
0.730108 4.172000 38.899617
0.710893 4.176000 38.936913
0.692007 4.180000 38.974208
0.673444 4.184000 39.011504
0.655169 4.188000 39.048800
0.637097 4.192000 39.086096
0.619219 4.196000 39.123392
0.601533 4.200000 39.160688
0.584039 4.204000 39.197984
0.566734 4.208000 39.235280
0.549617 4.212000 39.272576
0.532668 4.216000 39.309871
0.515903 4.220000 39.347167
0.499322 4.224000 39.384463
0.482922 4.228000 39.421759
0.466703 4.232000 39.459055
0.450662 4.236000 39.496351
0.434797 4.240000 39.533647
0.419107 4.244000 39.570943
0.403589 4.248000 39.608239
0.388240 4.252000 39.645535
0.373053 4.256000 39.682830
0.358025 4.260000 39.720126
0.343153 4.264000 39.757422
0.328433 4.268000 39.794718
0.313862 4.272000 39.832014
0.299437 4.276000 39.869310
0.285156 4.280000 39.906606
0.271013 4.284000 39.943902
0.257007 4.288000 39.981198
0.243132 4.292000 40.018493
0.229383 4.296000 40.055789
0.215754 4.300000 40.093085
0.202240 4.304000 40.130381
0.188830 4.308000 40.167677
0.175518 4.312000 40.204973
0.162291 4.316000 40.242269
0.149136 4.320000 40.279565
0.136037 4.324000 40.316861
0.122975 4.328000 40.354156
0.109923 4.332000 40.391452
0.096850 4.336000 40.428748
0.083713 4.340000 40.466044
0.070453 4.344000 40.503340
0.056987 4.348000 40.540636
0.043192 4.352000 40.577932
0.028879 4.356000 40.615228
0.013760 4.360000 40.652524
0.001928 4.363000 40.680496

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,920 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 70 MeV
70.000000 0.000000 0.000000
69.905134 0.015000 0.210854
69.810187 0.030000 0.421708
69.715160 0.045000 0.632562
69.620053 0.060000 0.843416
69.524866 0.075000 1.054270
69.429597 0.090000 1.265124
69.334248 0.105000 1.475978
69.238817 0.120000 1.686832
69.143304 0.135000 1.897686
69.047710 0.150000 2.108540
68.952034 0.165000 2.319394
68.856277 0.180000 2.530248
68.760436 0.195000 2.741102
68.664513 0.210000 2.951956
68.568508 0.225000 3.162810
68.472419 0.240000 3.373664
68.376248 0.255000 3.584518
68.279993 0.270000 3.795372
68.183654 0.285000 4.006226
68.087231 0.300000 4.217080
67.990725 0.315000 4.427934
67.894134 0.330000 4.638788
67.797459 0.345000 4.849642
67.700699 0.360000 5.060496
67.603854 0.375000 5.271350
67.506924 0.390000 5.482204
67.409908 0.405000 5.693058
67.312807 0.420000 5.903912
67.215620 0.435000 6.114766
67.118347 0.450000 6.325620
67.020988 0.465000 6.536474
66.923542 0.480000 6.747328
66.826009 0.495000 6.958182
66.728389 0.510000 7.169036
66.630682 0.525000 7.379890
66.532888 0.540000 7.590744
66.435006 0.555000 7.801598
66.337036 0.570000 8.012452
66.238977 0.585000 8.223306
66.140831 0.600000 8.434160
66.042595 0.615000 8.645014
65.944271 0.630000 8.855868
65.845858 0.645000 9.066722
65.747355 0.660000 9.277576
65.648762 0.675000 9.488430
65.550080 0.690000 9.699284
65.451307 0.705000 9.910138
65.352444 0.720000 10.120992
65.253491 0.735000 10.331846
65.154446 0.750000 10.542700
65.055311 0.765000 10.753554
64.956084 0.780000 10.964408
64.856765 0.795000 11.175262
64.757355 0.810000 11.386116
64.657852 0.825000 11.596970
64.558257 0.840000 11.807825
64.458569 0.855000 12.018679
64.358788 0.870000 12.229533
64.258914 0.885000 12.440387
64.158947 0.900000 12.651241
64.058886 0.915000 12.862095
63.958731 0.930000 13.072949
63.858481 0.945000 13.283803
63.758137 0.960000 13.494657
63.657698 0.975000 13.705511
63.557165 0.990000 13.916365
63.456535 1.005000 14.127219
63.355810 1.020000 14.338073
63.254990 1.035000 14.548927
63.154073 1.050000 14.759781
63.053060 1.065000 14.970635
62.951949 1.080000 15.181489
62.850742 1.095000 15.392343
62.749438 1.110000 15.603197
62.648036 1.125000 15.814051
62.546536 1.140000 16.024905
62.444938 1.155000 16.235759
62.343242 1.170000 16.446613
62.241447 1.185000 16.657467
62.139553 1.200000 16.868321
62.037559 1.215000 17.079175
61.935466 1.230000 17.290029
61.833274 1.245000 17.500883
61.730981 1.260000 17.711737
61.628587 1.275000 17.922591
61.526093 1.290000 18.133445
61.423497 1.305000 18.344299
61.320801 1.320000 18.555153
61.218002 1.335000 18.766007
61.115102 1.350000 18.976861
61.012099 1.365000 19.187715
60.908994 1.380000 19.398569
60.805786 1.395000 19.609423
60.702474 1.410000 19.820277
60.599059 1.425000 20.031131
60.495540 1.440000 20.241985
60.391917 1.455000 20.452839
60.288190 1.470000 20.663693
60.184358 1.485000 20.874547
60.080420 1.500000 21.085401
59.976378 1.515000 21.296255
59.872229 1.530000 21.507109
59.767974 1.545000 21.717963
59.663613 1.560000 21.928817
59.559146 1.575000 22.139671
59.454571 1.590000 22.350525
59.349888 1.605000 22.561379
59.245098 1.620000 22.772233
59.140200 1.635000 22.983087
59.035194 1.650000 23.193941
58.930079 1.665000 23.404795
58.824854 1.680000 23.615649
58.719521 1.695000 23.826503
58.614077 1.710000 24.037357
58.508524 1.725000 24.248211
58.402859 1.740000 24.459065
58.297085 1.755000 24.669919
58.191198 1.770000 24.880773
58.085201 1.785000 25.091627
57.979091 1.800000 25.302481
57.872870 1.815000 25.513335
57.766535 1.830000 25.724189
57.660088 1.845000 25.935043
57.553527 1.860000 26.145897
57.446853 1.875000 26.356751
57.340065 1.890000 26.567605
57.233162 1.905000 26.778459
57.126144 1.920000 26.989313
57.019012 1.935000 27.200167
56.911763 1.950000 27.411021
56.804399 1.965000 27.621875
56.696919 1.980000 27.832729
56.589322 1.995000 28.043583
56.481607 2.010000 28.254437
56.373776 2.025000 28.465291
56.265826 2.040000 28.676145
56.157759 2.055000 28.886999
56.049572 2.070000 29.097853
55.941267 2.085000 29.308707
55.832842 2.100000 29.519561
55.724298 2.115000 29.730415
55.615633 2.130000 29.941269
55.506848 2.145000 30.152123
55.397941 2.160000 30.362977
55.288914 2.175000 30.573831
55.179764 2.190000 30.784685
55.070492 2.205000 30.995539
54.961098 2.220000 31.206393
54.851580 2.235000 31.417247
54.741939 2.250000 31.628101
54.632174 2.265000 31.838955
54.522285 2.280000 32.049809
54.412271 2.295000 32.260663
54.302131 2.310000 32.471517
54.191866 2.325000 32.682371
54.081476 2.340000 32.893225
53.970958 2.355000 33.104079
53.860314 2.370000 33.314933
53.749542 2.385000 33.525787
53.638642 2.400000 33.736641
53.527615 2.415000 33.947495
53.416458 2.430000 34.158349
53.305172 2.445000 34.369203
53.193757 2.460000 34.580057
53.082212 2.475000 34.790911
52.970536 2.490000 35.001765
52.858729 2.505000 35.212619
52.746790 2.520000 35.423474
52.634720 2.535000 35.634328
52.522517 2.550000 35.845182
52.410182 2.565000 36.056036
52.297713 2.580000 36.266890
52.185110 2.595000 36.477744
52.072373 2.610000 36.688598
51.959501 2.625000 36.899452
51.846494 2.640000 37.110306
51.733350 2.655000 37.321160
51.620071 2.670000 37.532014
51.506655 2.685000 37.742868
51.393102 2.700000 37.953722
51.279411 2.715000 38.164576
51.165581 2.730000 38.375430
51.051613 2.745000 38.586284
50.937506 2.760000 38.797138
50.823258 2.775000 39.007992
50.708870 2.790000 39.218846
50.594342 2.805000 39.429700
50.479672 2.820000 39.640554
50.364860 2.835000 39.851408
50.249906 2.850000 40.062262
50.134808 2.865000 40.273116
50.019568 2.880000 40.483970
49.904183 2.895000 40.694824
49.788653 2.910000 40.905678
49.672978 2.925000 41.116532
49.557158 2.940000 41.327386
49.441191 2.955000 41.538240
49.325078 2.970000 41.749094
49.208817 2.985000 41.959948
49.092408 3.000000 42.170802
48.975850 3.015000 42.381656
48.859143 3.030000 42.592510
48.742287 3.045000 42.803364
48.625280 3.060000 43.014218
48.508123 3.075000 43.225072
48.390814 3.090000 43.435926
48.273353 3.105000 43.646780
48.155739 3.120000 43.857634
48.037972 3.135000 44.068488
47.920051 3.150000 44.279342
47.801976 3.165000 44.490196
47.683746 3.180000 44.701050
47.565360 3.195000 44.911904
47.446817 3.210000 45.122758
47.328118 3.225000 45.333612
47.209261 3.240000 45.544466
47.090245 3.255000 45.755320
46.971071 3.270000 45.966174
46.851738 3.285000 46.177028
46.732244 3.300000 46.387882
46.612589 3.315000 46.598736
46.492773 3.330000 46.809590
46.372795 3.345000 47.020444
46.252654 3.360000 47.231298
46.132349 3.375000 47.442152
46.011881 3.390000 47.653006
45.891247 3.405000 47.863860
45.770448 3.420000 48.074714
45.649483 3.435000 48.285568
45.528350 3.450000 48.496422
45.407051 3.465000 48.707276
45.285582 3.480000 48.918130
45.163945 3.495000 49.128984
45.042138 3.510000 49.339838
44.920161 3.525000 49.550692
44.798012 3.540000 49.761546
44.675692 3.555000 49.972400
44.553198 3.570000 50.183254
44.430532 3.585000 50.394108
44.307691 3.600000 50.604962
44.184675 3.615000 50.815816
44.061484 3.630000 51.026670
43.938116 3.645000 51.237524
43.814570 3.660000 51.448378
43.690847 3.675000 51.659232
43.566945 3.690000 51.870086
43.442864 3.705000 52.080940
43.318602 3.720000 52.291794
43.194159 3.735000 52.502648
43.069534 3.750000 52.713502
42.944726 3.765000 52.924356
42.819735 3.780000 53.135210
42.694559 3.795000 53.346064
42.569198 3.810000 53.556918
42.443650 3.825000 53.767772
42.317916 3.840000 53.978626
42.191994 3.855000 54.189480
42.065883 3.870000 54.400334
41.939583 3.885000 54.611188
41.813092 3.900000 54.822042
41.686410 3.915000 55.032896
41.559536 3.930000 55.243750
41.432469 3.945000 55.454604
41.305208 3.960000 55.665458
41.177752 3.975000 55.876312
41.050100 3.990000 56.087166
40.922251 4.005000 56.298020
40.794205 4.020000 56.508874
40.665960 4.035000 56.719728
40.537515 4.050000 56.930582
40.408871 4.065000 57.141436
40.280024 4.080000 57.352290
40.150975 4.095000 57.563144
40.021723 4.110000 57.773998
39.892266 4.125000 57.984852
39.762604 4.140000 58.195706
39.632736 4.155000 58.406560
39.502660 4.170000 58.617414
39.372376 4.185000 58.828269
39.241882 4.200000 59.039123
39.111178 4.215000 59.249977
38.980262 4.230000 59.460831
38.849133 4.245000 59.671685
38.717791 4.260000 59.882539
38.586234 4.275000 60.093393
38.454461 4.290000 60.304247
38.322472 4.305000 60.515101
38.190264 4.320000 60.725955
38.057837 4.335000 60.936809
37.925190 4.350000 61.147663
37.792321 4.365000 61.358517
37.659230 4.380000 61.569371
37.525915 4.395000 61.780225
37.392375 4.410000 61.991079
37.258609 4.425000 62.201933
37.124615 4.440000 62.412787
36.990394 4.455000 62.623641
36.855942 4.470000 62.834495
36.721260 4.485000 63.045349
36.586345 4.500000 63.256203
36.451197 4.515000 63.467057
36.315814 4.530000 63.677911
36.180196 4.545000 63.888765
36.044340 4.560000 64.099619
35.908246 4.575000 64.310473
35.771911 4.590000 64.521327
35.635336 4.605000 64.732181
35.498518 4.620000 64.943035
35.361456 4.635000 65.153889
35.224149 4.650000 65.364743
35.086596 4.665000 65.575597
34.948794 4.680000 65.786451
34.810743 4.695000 65.997305
34.672441 4.710000 66.208159
34.533887 4.725000 66.419013
34.395079 4.740000 66.629867
34.256016 4.755000 66.840721
34.116697 4.770000 67.051575
33.977119 4.785000 67.262429
33.837281 4.800000 67.473283
33.697182 4.815000 67.684137
33.556821 4.830000 67.894991
33.416195 4.845000 68.105845
33.275303 4.860000 68.316699
33.134144 4.875000 68.527553
32.992715 4.890000 68.738407
32.851016 4.905000 68.949261
32.709044 4.920000 69.160115
32.566799 4.935000 69.370969
32.424277 4.950000 69.581823
32.281478 4.965000 69.792677
32.138399 4.980000 70.003531
31.995040 4.995000 70.214385
31.851398 5.010000 70.425239
31.707471 5.025000 70.636093
31.563258 5.040000 70.846947
31.418756 5.055000 71.057801
31.273964 5.070000 71.268655
31.128881 5.085000 71.479509
30.983503 5.100000 71.690363
30.837830 5.115000 71.901217
30.691858 5.130000 72.112071
30.545587 5.145000 72.322925
30.399014 5.160000 72.533779
30.252137 5.175000 72.744633
30.104955 5.190000 72.955487
29.957464 5.205000 73.166341
29.809663 5.220000 73.377195
29.661549 5.235000 73.588049
29.513122 5.250000 73.798903
29.364377 5.265000 74.009757
29.215314 5.280000 74.220611
29.065929 5.295000 74.431465
28.916221 5.310000 74.642319
28.766187 5.325000 74.853173
28.615825 5.340000 75.064027
28.465132 5.355000 75.274881
28.314106 5.370000 75.485735
28.162745 5.385000 75.696589
28.011045 5.400000 75.907443
27.859005 5.415000 76.118297
27.706622 5.430000 76.329151
27.553893 5.445000 76.540005
27.400815 5.460000 76.750859
27.247386 5.475000 76.961713
27.093603 5.490000 77.172567
26.939463 5.505000 77.383421
26.784964 5.520000 77.594275
26.630102 5.535000 77.805129
26.474874 5.550000 78.015983
26.319278 5.565000 78.226837
26.163310 5.580000 78.437691
26.006968 5.595000 78.648545
25.850248 5.610000 78.859399
25.693147 5.625000 79.070253
25.535662 5.640000 79.281107
25.377788 5.655000 79.491961
25.219524 5.670000 79.702815
25.060866 5.685000 79.913669
24.901809 5.700000 80.124523
24.742351 5.715000 80.335377
24.582487 5.730000 80.546231
24.422215 5.745000 80.757085
24.261530 5.760000 80.967939
24.100428 5.775000 81.178793
23.938905 5.790000 81.389647
23.776958 5.805000 81.600501
23.614582 5.820000 81.811355
23.451773 5.835000 82.022209
23.288526 5.850000 82.233064
23.124838 5.865000 82.443918
22.960703 5.880000 82.654772
22.796118 5.895000 82.865626
22.631077 5.910000 83.076480
22.465576 5.925000 83.287334
22.299609 5.940000 83.498188
22.133172 5.955000 83.709042
21.966259 5.970000 83.919896
21.798866 5.985000 84.130750
21.630986 6.000000 84.341604
21.462615 6.015000 84.552458
21.293768 6.030000 84.763312
21.124481 6.045000 84.974166
20.954756 6.060000 85.185020
20.784589 6.075000 85.395874
20.613976 6.090000 85.606728
20.442914 6.105000 85.817582
20.271399 6.120000 86.028436
20.099430 6.135000 86.239290
19.927001 6.150000 86.450144
19.754110 6.165000 86.660998
19.580753 6.180000 86.871852
19.406927 6.195000 87.082706
19.232628 6.210000 87.293560
19.057851 6.225000 87.504414
18.882595 6.240000 87.715268
18.706854 6.255000 87.926122
18.530626 6.270000 88.136976
18.353906 6.285000 88.347830
18.176690 6.300000 88.558684
17.998975 6.315000 88.769538
17.820756 6.330000 88.980392
17.642030 6.345000 89.191246
17.462792 6.360000 89.402100
17.283038 6.375000 89.612954
17.102765 6.390000 89.823808
16.921967 6.405000 90.034662
16.740641 6.420000 90.245516
16.558782 6.435000 90.456370
16.522346 6.438000 90.498541
16.485888 6.441000 90.540711
16.449409 6.444000 90.582882
16.412908 6.447000 90.625053
16.376386 6.450000 90.667224
16.339841 6.453000 90.709395
16.303276 6.456000 90.751565
16.266688 6.459000 90.793736
16.230079 6.462000 90.835907
16.193448 6.465000 90.878078
16.156795 6.468000 90.920249
16.120120 6.471000 90.962419
16.083423 6.474000 91.004590
16.046704 6.477000 91.046761
16.009963 6.480000 91.088932
15.973200 6.483000 91.131103
15.936416 6.486000 91.173273
15.899609 6.489000 91.215444
15.862779 6.492000 91.257615
15.825928 6.495000 91.299786
15.789055 6.498000 91.341957
15.752159 6.501000 91.384127
15.715241 6.504000 91.426298
15.678300 6.507000 91.468469
15.641338 6.510000 91.510640
15.604352 6.513000 91.552811
15.567345 6.516000 91.594982
15.530315 6.519000 91.637152
15.493262 6.522000 91.679323
15.456187 6.525000 91.721494
15.419089 6.528000 91.763665
15.381969 6.531000 91.805836
15.344826 6.534000 91.848006
15.307660 6.537000 91.890177
15.270471 6.540000 91.932348
15.233260 6.543000 91.974519
15.196026 6.546000 92.016690
15.158769 6.549000 92.058860
15.121489 6.552000 92.101031
15.084186 6.555000 92.143202
15.046860 6.558000 92.185373
15.009511 6.561000 92.227544
14.972139 6.564000 92.269714
14.934744 6.567000 92.311885
14.897326 6.570000 92.354056
14.859885 6.573000 92.396227
14.822420 6.576000 92.438398
14.784932 6.579000 92.480568
14.747421 6.582000 92.522739
14.709886 6.585000 92.564910
14.672329 6.588000 92.607081
14.634747 6.591000 92.649252
14.597143 6.594000 92.691422
14.559514 6.597000 92.733593
14.521863 6.600000 92.775764
14.484187 6.603000 92.817935
14.446488 6.606000 92.860106
14.408766 6.609000 92.902276
14.371019 6.612000 92.944447
14.333249 6.615000 92.986618
14.295456 6.618000 93.028789
14.257638 6.621000 93.070960
14.219796 6.624000 93.113130
14.181931 6.627000 93.155301
14.144042 6.630000 93.197472
14.106128 6.633000 93.239643
14.068191 6.636000 93.281814
14.030230 6.639000 93.323984
13.992244 6.642000 93.366155
13.954235 6.645000 93.408326
13.916201 6.648000 93.450497
13.878143 6.651000 93.492668
13.840060 6.654000 93.534838
13.801954 6.657000 93.577009
13.763823 6.660000 93.619180
13.725667 6.663000 93.661351
13.687488 6.666000 93.703522
13.649283 6.669000 93.745692
13.611055 6.672000 93.787863
13.572801 6.675000 93.830034
13.534523 6.678000 93.872205
13.496221 6.681000 93.914376
13.457894 6.684000 93.956546
13.419542 6.687000 93.998717
13.381165 6.690000 94.040888
13.342764 6.693000 94.083059
13.304337 6.696000 94.125230
13.265886 6.699000 94.167400
13.227410 6.702000 94.209571
13.188909 6.705000 94.251742
13.150383 6.708000 94.293913
13.111832 6.711000 94.336084
13.073256 6.714000 94.378254
13.034655 6.717000 94.420425
12.996028 6.720000 94.462596
12.957376 6.723000 94.504767
12.918700 6.726000 94.546938
12.879997 6.729000 94.589108
12.841270 6.732000 94.631279
12.802517 6.735000 94.673450
12.763739 6.738000 94.715621
12.724935 6.741000 94.757792
12.686106 6.744000 94.799962
12.647251 6.747000 94.842133
12.608371 6.750000 94.884304
12.569465 6.753000 94.926475
12.530534 6.756000 94.968646
12.491576 6.759000 95.010816
12.452593 6.762000 95.052987
12.413585 6.765000 95.095158
12.374550 6.768000 95.137329
12.335490 6.771000 95.179500
12.296404 6.774000 95.221670
12.257292 6.777000 95.263841
12.218154 6.780000 95.306012
12.178990 6.783000 95.348183
12.139800 6.786000 95.390354
12.100585 6.789000 95.432524
12.061349 6.792000 95.474695
12.022092 6.795000 95.516866
11.982814 6.798000 95.559037
11.943515 6.801000 95.601208
11.904196 6.804000 95.643378
11.864856 6.807000 95.685549
11.825496 6.810000 95.727720
11.786115 6.813000 95.769891
11.746714 6.816000 95.812062
11.707293 6.819000 95.854232
11.667851 6.822000 95.896403
11.628389 6.825000 95.938574
11.588906 6.828000 95.980745
11.549403 6.831000 96.022916
11.509880 6.834000 96.065086
11.470337 6.837000 96.107257
11.430774 6.840000 96.149428
11.391191 6.843000 96.191599
11.351587 6.846000 96.233770
11.311963 6.849000 96.275941
11.272320 6.852000 96.318111
11.232656 6.855000 96.360282
11.192973 6.858000 96.402453
11.153270 6.861000 96.444624
11.113546 6.864000 96.486795
11.073804 6.867000 96.528965
11.034041 6.870000 96.571136
10.994259 6.873000 96.613307
10.954457 6.876000 96.655478
10.914635 6.879000 96.697649
10.874794 6.882000 96.739819
10.834934 6.885000 96.781990
10.795054 6.888000 96.824161
10.755155 6.891000 96.866332
10.715237 6.894000 96.908503
10.675299 6.897000 96.950673
10.635342 6.900000 96.992844
10.595367 6.903000 97.035015
10.555372 6.906000 97.077186
10.515358 6.909000 97.119357
10.475326 6.912000 97.161527
10.435274 6.915000 97.203698
10.395205 6.918000 97.245869
10.355116 6.921000 97.288040
10.315009 6.924000 97.330211
10.274884 6.927000 97.372381
10.234740 6.930000 97.414552
10.194578 6.933000 97.456723
10.154398 6.936000 97.498894
10.114200 6.939000 97.541065
10.073984 6.942000 97.583235
10.033750 6.945000 97.625406
9.993499 6.948000 97.667577
9.953229 6.951000 97.709748
9.912943 6.954000 97.751919
9.872639 6.957000 97.794089
9.832318 6.960000 97.836260
9.791979 6.963000 97.878431
9.751624 6.966000 97.920602
9.711251 6.969000 97.962773
9.670862 6.972000 98.004943
9.630457 6.975000 98.047114
9.590035 6.978000 98.089285
9.549596 6.981000 98.131456
9.509142 6.984000 98.173627
9.468671 6.987000 98.215797
9.428185 6.990000 98.257968
9.387683 6.993000 98.300139
9.347165 6.996000 98.342310
9.306632 6.999000 98.384481
9.266084 7.002000 98.426651
9.225521 7.005000 98.468822
9.184943 7.008000 98.510993
9.144351 7.011000 98.553164
9.103744 7.014000 98.595335
9.063122 7.017000 98.637505
9.022487 7.020000 98.679676
8.981838 7.023000 98.721847
8.941175 7.026000 98.764018
8.900499 7.029000 98.806189
8.859810 7.032000 98.848359
8.819108 7.035000 98.890530
8.778393 7.038000 98.932701
8.737666 7.041000 98.974872
8.696926 7.044000 99.017043
8.656175 7.047000 99.059213
8.615412 7.050000 99.101384
8.574637 7.053000 99.143555
8.533852 7.056000 99.185726
8.493056 7.059000 99.227897
8.452249 7.062000 99.270067
8.411432 7.065000 99.312238
8.370605 7.068000 99.354409
8.329768 7.071000 99.396580
8.288922 7.074000 99.438751
8.248067 7.077000 99.480921
8.207204 7.080000 99.523092
8.166332 7.083000 99.565263
8.125453 7.086000 99.607434
8.084566 7.089000 99.649605
8.043672 7.092000 99.691775
8.002771 7.095000 99.733946
7.961863 7.098000 99.776117
7.920950 7.101000 99.818288
7.880031 7.104000 99.860459
7.839107 7.107000 99.902629
7.798179 7.110000 99.944800
7.757246 7.113000 99.986971
7.716310 7.116000 100.029142
7.675370 7.119000 100.071313
7.634428 7.122000 100.113483
7.593483 7.125000 100.155654
7.552537 7.128000 100.197825
7.511589 7.131000 100.239996
7.470640 7.134000 100.282167
7.429692 7.137000 100.324337
7.388744 7.140000 100.366508
7.347797 7.143000 100.408679
7.306851 7.146000 100.450850
7.265908 7.149000 100.493021
7.224967 7.152000 100.535191
7.184030 7.155000 100.577362
7.143097 7.158000 100.619533
7.102169 7.161000 100.661704
7.061246 7.164000 100.703875
7.020316 7.167000 100.746045
6.979366 7.170000 100.788216
6.938396 7.173000 100.830387
6.897407 7.176000 100.872558
6.856397 7.179000 100.914729
6.815367 7.182000 100.956900
6.774316 7.185000 100.999070
6.733246 7.188000 101.041241
6.692156 7.191000 101.083412
6.651047 7.194000 101.125583
6.609919 7.197000 101.167754
6.568772 7.200000 101.209924
6.527608 7.203000 101.252095
6.486426 7.206000 101.294266
6.445228 7.209000 101.336437
6.404012 7.212000 101.378608
6.362781 7.215000 101.420778
6.321533 7.218000 101.462949
6.280271 7.221000 101.505120
6.238994 7.224000 101.547291
6.197703 7.227000 101.589462
6.156399 7.230000 101.631632
6.115082 7.233000 101.673803
6.073753 7.236000 101.715974
6.032412 7.239000 101.758145
5.991060 7.242000 101.800316
5.949698 7.245000 101.842486
5.908326 7.248000 101.884657
5.866946 7.251000 101.926828
5.825558 7.254000 101.968999
5.784163 7.257000 102.011170
5.742761 7.260000 102.053340
5.701353 7.263000 102.095511
5.659942 7.266000 102.137682
5.618526 7.269000 102.179853
5.577107 7.272000 102.222024
5.535687 7.275000 102.264194
5.494266 7.278000 102.306365
5.452845 7.281000 102.348536
5.411425 7.284000 102.390707
5.370008 7.287000 102.432878
5.328594 7.290000 102.475048
5.287185 7.293000 102.517219
5.245782 7.296000 102.559390
5.204385 7.299000 102.601561
5.162997 7.302000 102.643732
5.121619 7.305000 102.685902
5.080252 7.308000 102.728073
5.038898 7.311000 102.770244
4.997557 7.314000 102.812415
4.956232 7.317000 102.854586
4.914923 7.320000 102.896756
4.873633 7.323000 102.938927
4.832364 7.326000 102.981098
4.791116 7.329000 103.023269
4.749891 7.332000 103.065440
4.708692 7.335000 103.107610
4.667520 7.338000 103.149781
4.626377 7.341000 103.191952
4.585264 7.344000 103.234123
4.544185 7.347000 103.276294
4.503140 7.350000 103.318464
4.462132 7.353000 103.360635
4.421163 7.356000 103.402806
4.380236 7.359000 103.444977
4.339351 7.362000 103.487148
4.298512 7.365000 103.529318
4.257722 7.368000 103.571489
4.216981 7.371000 103.613660
4.176294 7.374000 103.655831
4.135662 7.377000 103.698002
4.095087 7.380000 103.740172
4.054574 7.383000 103.782343
4.014123 7.386000 103.824514
3.973738 7.389000 103.866685
3.933422 7.392000 103.908856
3.893177 7.395000 103.951026
3.853007 7.398000 103.993197
3.812914 7.401000 104.035368
3.772902 7.404000 104.077539
3.732973 7.407000 104.119710
3.693131 7.410000 104.161880
3.653378 7.413000 104.204051
3.613718 7.416000 104.246222
3.574155 7.419000 104.288393
3.534691 7.422000 104.330564
3.495330 7.425000 104.372734
3.456075 7.428000 104.414905
3.416931 7.431000 104.457076
3.377899 7.434000 104.499247
3.338985 7.437000 104.541418
3.300191 7.440000 104.583588
3.261521 7.443000 104.625759
3.222980 7.446000 104.667930
3.184570 7.449000 104.710101
3.146295 7.452000 104.752272
3.108159 7.455000 104.794442
3.070167 7.458000 104.836613
3.032321 7.461000 104.878784
2.994626 7.464000 104.920955
2.957085 7.467000 104.963126
2.919703 7.470000 105.005296
2.882483 7.473000 105.047467
2.845430 7.476000 105.089638
2.808546 7.479000 105.131809
2.771837 7.482000 105.173980
2.735306 7.485000 105.216150
2.698957 7.488000 105.258321
2.662793 7.491000 105.300492
2.626820 7.494000 105.342663
2.591039 7.497000 105.384834
2.555457 7.500000 105.427004
2.520075 7.503000 105.469175
2.484899 7.506000 105.511346
2.449931 7.509000 105.553517
2.415176 7.512000 105.595688
2.380637 7.515000 105.637858
2.346318 7.518000 105.680029
2.312222 7.521000 105.722200
2.278352 7.524000 105.764371
2.244713 7.527000 105.806542
2.211308 7.530000 105.848713
2.178139 7.533000 105.890883
2.145210 7.536000 105.933054
2.112525 7.539000 105.975225
2.080086 7.542000 106.017396
2.047896 7.545000 106.059567
2.015958 7.548000 106.101737
1.984275 7.551000 106.143908
1.952849 7.554000 106.186079
1.921683 7.557000 106.228250
1.890780 7.560000 106.270421
1.860142 7.563000 106.312591
1.829771 7.566000 106.354762
1.799669 7.569000 106.396933
1.769838 7.572000 106.439104
1.740280 7.575000 106.481275
1.710997 7.578000 106.523445
1.681991 7.581000 106.565616
1.653262 7.584000 106.607787
1.624813 7.587000 106.649958
1.596645 7.590000 106.692129
1.568758 7.593000 106.734299
1.541155 7.596000 106.776470
1.513835 7.599000 106.818641
1.486799 7.602000 106.860812
1.460049 7.605000 106.902983
1.433585 7.608000 106.945153
1.407406 7.611000 106.987324
1.381514 7.614000 107.029495
1.355909 7.617000 107.071666
1.330590 7.620000 107.113837
1.305557 7.623000 107.156007
1.280811 7.626000 107.198178
1.256350 7.629000 107.240349
1.232175 7.632000 107.282520
1.208285 7.635000 107.324691
1.184680 7.638000 107.366861
1.161357 7.641000 107.409032
1.138318 7.644000 107.451203
1.115560 7.647000 107.493374
1.093083 7.650000 107.535545
1.070885 7.653000 107.577715
1.048965 7.656000 107.619886
1.027322 7.659000 107.662057
1.005955 7.662000 107.704228
0.984862 7.665000 107.746399
0.964041 7.668000 107.788569
0.943491 7.671000 107.830740
0.923209 7.674000 107.872911
0.903195 7.677000 107.915082
0.883447 7.680000 107.957253
0.863961 7.683000 107.999423
0.844737 7.686000 108.041594
0.825773 7.689000 108.083765
0.807066 7.692000 108.125936
0.788613 7.695000 108.168107
0.770414 7.698000 108.210277
0.752466 7.701000 108.252448
0.734766 7.704000 108.294619
0.717312 7.707000 108.336790
0.700102 7.710000 108.378961
0.683133 7.713000 108.421131
0.666403 7.716000 108.463302
0.649910 7.719000 108.505473
0.633651 7.722000 108.547644
0.617624 7.725000 108.589815
0.601826 7.728000 108.631985
0.586254 7.731000 108.674156
0.570907 7.734000 108.716327
0.555782 7.737000 108.758498
0.540875 7.740000 108.800669
0.526185 7.743000 108.842839
0.511709 7.746000 108.885010
0.497445 7.749000 108.927181
0.483389 7.752000 108.969352
0.469539 7.755000 109.011523
0.455894 7.758000 109.053693
0.442449 7.761000 109.095864
0.429203 7.764000 109.138035
0.416149 7.767000 109.180206
0.403272 7.770000 109.222377
0.390573 7.773000 109.264547
0.378051 7.776000 109.306718
0.365705 7.779000 109.348889
0.353536 7.782000 109.391060
0.341541 7.785000 109.433231
0.329722 7.788000 109.475401
0.318078 7.791000 109.517572
0.306607 7.794000 109.559743
0.295309 7.797000 109.601914
0.284183 7.800000 109.644085
0.273230 7.803000 109.686255
0.262448 7.806000 109.728426
0.251836 7.809000 109.770597
0.241390 7.812000 109.812768
0.231104 7.815000 109.854939
0.220985 7.818000 109.897109
0.211029 7.821000 109.939280
0.201238 7.824000 109.981451
0.191609 7.827000 110.023622
0.182142 7.830000 110.065793
0.172836 7.833000 110.107963
0.163689 7.836000 110.150134
0.154702 7.839000 110.192305
0.145871 7.842000 110.234476
0.137196 7.845000 110.276647
0.128676 7.848000 110.318817
0.120307 7.851000 110.360988
0.112087 7.854000 110.403159
0.104015 7.857000 110.445330
0.096086 7.860000 110.487501
0.088296 7.863000 110.529672
0.080642 7.866000 110.571842
0.073118 7.869000 110.614013
0.065716 7.872000 110.656184
0.058429 7.875000 110.698355
0.051244 7.878000 110.740526
0.044148 7.881000 110.782696
0.037121 7.884000 110.824867
0.030134 7.887000 110.867038
0.023148 7.890000 110.909209
0.016101 7.893000 110.951380
0.008898 7.896000 110.993550
0.001482 7.899000 111.035721

View File

@ -0,0 +1,881 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 70 MeV
70.000000 0.000000 0.000000
69.897349 0.016000 0.208857
69.794605 0.032000 0.417714
69.691767 0.048000 0.626571
69.588835 0.064000 0.835428
69.485809 0.080000 1.044285
69.382688 0.096000 1.253142
69.279472 0.112000 1.461999
69.176161 0.128000 1.670856
69.072755 0.144000 1.879713
68.969253 0.160000 2.088570
68.865656 0.176000 2.297427
68.761962 0.192000 2.506284
68.658172 0.208000 2.715141
68.554285 0.224000 2.923998
68.450301 0.240000 3.132855
68.346220 0.256000 3.341712
68.242041 0.272000 3.550569
68.137765 0.288000 3.759426
68.033391 0.304000 3.968283
67.928918 0.320000 4.177140
67.824346 0.336000 4.385997
67.719676 0.352000 4.594854
67.614907 0.368000 4.803711
67.510038 0.384000 5.012568
67.405069 0.400000 5.221425
67.300000 0.416000 5.430282
67.194831 0.432000 5.639139
67.089561 0.448000 5.847996
66.984191 0.464000 6.056853
66.878719 0.480000 6.265710
66.773146 0.496000 6.474567
66.667471 0.512000 6.683424
66.561693 0.528000 6.892281
66.455814 0.544000 7.101138
66.349832 0.560000 7.309995
66.243746 0.576000 7.518852
66.137558 0.592000 7.727709
66.031266 0.608000 7.936566
65.924870 0.624000 8.145423
65.818369 0.640000 8.354280
65.711764 0.656000 8.563137
65.605055 0.672000 8.771994
65.498240 0.688000 8.980851
65.391320 0.704000 9.189708
65.284294 0.720000 9.398565
65.177162 0.736000 9.607422
65.069923 0.752000 9.816279
64.962578 0.768000 10.025136
64.855126 0.784000 10.233993
64.747566 0.800000 10.442850
64.639899 0.816000 10.651707
64.532124 0.832000 10.860564
64.424240 0.848000 11.069421
64.316248 0.864000 11.278278
64.208146 0.880000 11.487135
64.099936 0.896000 11.695992
63.991615 0.912000 11.904849
63.883185 0.928000 12.113706
63.774644 0.944000 12.322563
63.665993 0.960000 12.531420
63.557230 0.976000 12.740277
63.448356 0.992000 12.949134
63.339371 1.008000 13.157991
63.230273 1.024000 13.366848
63.121063 1.040000 13.575705
63.011741 1.056000 13.784562
62.902305 1.072000 13.993419
62.792755 1.088000 14.202276
62.683092 1.104000 14.411133
62.573315 1.120000 14.619990
62.463423 1.136000 14.828847
62.353416 1.152000 15.037704
62.243294 1.168000 15.246561
62.133056 1.184000 15.455418
62.022703 1.200000 15.664275
61.912233 1.216000 15.873132
61.801646 1.232000 16.081989
61.690942 1.248000 16.290846
61.580120 1.264000 16.499703
61.469181 1.280000 16.708560
61.358124 1.296000 16.917417
61.246947 1.312000 17.126274
61.135652 1.328000 17.335131
61.024238 1.344000 17.543988
60.912703 1.360000 17.752845
60.801049 1.376000 17.961702
60.689274 1.392000 18.170559
60.577378 1.408000 18.379416
60.465360 1.424000 18.588273
60.353221 1.440000 18.797130
60.240960 1.456000 19.005987
60.128576 1.472000 19.214844
60.016069 1.488000 19.423701
59.903439 1.504000 19.632558
59.790685 1.520000 19.841415
59.677807 1.536000 20.050272
59.564804 1.552000 20.259129
59.451677 1.568000 20.467986
59.338424 1.584000 20.676843
59.225044 1.600000 20.885700
59.111539 1.616000 21.094557
58.997907 1.632000 21.303414
58.884148 1.648000 21.512271
58.770261 1.664000 21.721128
58.656247 1.680000 21.929985
58.542103 1.696000 22.138842
58.427831 1.712000 22.347699
58.313430 1.728000 22.556556
58.198899 1.744000 22.765413
58.084238 1.760000 22.974270
57.969446 1.776000 23.183127
57.854523 1.792000 23.391984
57.739468 1.808000 23.600841
57.624282 1.824000 23.809698
57.508963 1.840000 24.018555
57.393511 1.856000 24.227412
57.277926 1.872000 24.436269
57.162206 1.888000 24.645126
57.046353 1.904000 24.853983
56.930365 1.920000 25.062840
56.814241 1.936000 25.271697
56.697982 1.952000 25.480554
56.581586 1.968000 25.689411
56.465054 1.984000 25.898268
56.348385 2.000000 26.107125
56.231577 2.016000 26.315982
56.114632 2.032000 26.524839
55.997548 2.048000 26.733696
55.880325 2.064000 26.942553
55.762962 2.080000 27.151410
55.645459 2.096000 27.360267
55.527816 2.112000 27.569124
55.410031 2.128000 27.777981
55.292104 2.144000 27.986838
55.174035 2.160000 28.195695
55.055824 2.176000 28.404552
54.937469 2.192000 28.613409
54.818971 2.208000 28.822266
54.700328 2.224000 29.031123
54.581540 2.240000 29.239980
54.462607 2.256000 29.448837
54.343528 2.272000 29.657694
54.224302 2.288000 29.866551
54.104930 2.304000 30.075408
53.985410 2.320000 30.284265
53.865742 2.336000 30.493122
53.745925 2.352000 30.701979
53.625959 2.368000 30.910836
53.505843 2.384000 31.119693
53.385577 2.400000 31.328550
53.265160 2.416000 31.537407
53.144591 2.432000 31.746264
53.023870 2.448000 31.955121
52.902997 2.464000 32.163978
52.781970 2.480000 32.372835
52.660790 2.496000 32.581692
52.539455 2.512000 32.790549
52.417965 2.528000 32.999406
52.296319 2.544000 33.208263
52.174518 2.560000 33.417120
52.052559 2.576000 33.625977
51.930443 2.592000 33.834834
51.808169 2.608000 34.043691
51.685736 2.624000 34.252548
51.563144 2.640000 34.461405
51.440392 2.656000 34.670262
51.317480 2.672000 34.879119
51.194406 2.688000 35.087976
51.071170 2.704000 35.296833
50.947772 2.720000 35.505690
50.824211 2.736000 35.714547
50.700486 2.752000 35.923404
50.576596 2.768000 36.132261
50.452542 2.784000 36.341118
50.328321 2.800000 36.549975
50.203934 2.816000 36.758832
50.079380 2.832000 36.967689
49.954658 2.848000 37.176546
49.829768 2.864000 37.385403
49.704709 2.880000 37.594260
49.579479 2.896000 37.803117
49.454079 2.912000 38.011974
49.328508 2.928000 38.220831
49.202765 2.944000 38.429688
49.076849 2.960000 38.638545
48.950759 2.976000 38.847402
48.824496 2.992000 39.056259
48.698057 3.008000 39.265116
48.571443 3.024000 39.473973
48.444652 3.040000 39.682830
48.317685 3.056000 39.891687
48.190539 3.072000 40.100544
48.063215 3.088000 40.309401
47.935712 3.104000 40.518258
47.808028 3.120000 40.727115
47.680163 3.136000 40.935972
47.552117 3.152000 41.144829
47.423888 3.168000 41.353686
47.295476 3.184000 41.562543
47.166880 3.200000 41.771400
47.038099 3.216000 41.980257
46.909132 3.232000 42.189114
46.779979 3.248000 42.397971
46.650638 3.264000 42.606828
46.521109 3.280000 42.815685
46.391391 3.296000 43.024542
46.261484 3.312000 43.233399
46.131385 3.328000 43.442256
46.001095 3.344000 43.651113
45.870613 3.360000 43.859970
45.739938 3.376000 44.068827
45.609068 3.392000 44.277684
45.478004 3.408000 44.486541
45.346743 3.424000 44.695398
45.215286 3.440000 44.904255
45.083631 3.456000 45.113112
44.951777 3.472000 45.321969
44.819724 3.488000 45.530826
44.687471 3.504000 45.739683
44.555016 3.520000 45.948540
44.422359 3.536000 46.157397
44.289498 3.552000 46.366254
44.156434 3.568000 46.575111
44.023164 3.584000 46.783968
43.889688 3.600000 46.992825
43.756005 3.616000 47.201682
43.622115 3.632000 47.410540
43.488015 3.648000 47.619397
43.353705 3.664000 47.828254
43.219183 3.680000 48.037111
43.084450 3.696000 48.245968
42.949504 3.712000 48.454825
42.814344 3.728000 48.663682
42.678968 3.744000 48.872539
42.543376 3.760000 49.081396
42.407567 3.776000 49.290253
42.271540 3.792000 49.499110
42.135293 3.808000 49.707967
41.998826 3.824000 49.916824
41.862137 3.840000 50.125681
41.725226 3.856000 50.334538
41.588090 3.872000 50.543395
41.450730 3.888000 50.752252
41.313144 3.904000 50.961109
41.175330 3.920000 51.169966
41.037289 3.936000 51.378823
40.899017 3.952000 51.587680
40.760515 3.968000 51.796537
40.621781 3.984000 52.005394
40.482814 4.000000 52.214251
40.343613 4.016000 52.423108
40.204176 4.032000 52.631965
40.064502 4.048000 52.840822
39.924591 4.064000 53.049679
39.784440 4.080000 53.258536
39.644049 4.096000 53.467393
39.503416 4.112000 53.676250
39.362540 4.128000 53.885107
39.221420 4.144000 54.093964
39.080054 4.160000 54.302821
38.938442 4.176000 54.511678
38.796580 4.192000 54.720535
38.654470 4.208000 54.929392
38.512108 4.224000 55.138249
38.369494 4.240000 55.347106
38.226626 4.256000 55.555963
38.083503 4.272000 55.764820
37.940124 4.288000 55.973677
37.796486 4.304000 56.182534
37.652589 4.320000 56.391391
37.508431 4.336000 56.600248
37.364011 4.352000 56.809105
37.219327 4.368000 57.017962
37.074378 4.384000 57.226819
36.929162 4.400000 57.435676
36.783677 4.416000 57.644533
36.637922 4.432000 57.853390
36.491896 4.448000 58.062247
36.345597 4.464000 58.271104
36.199023 4.480000 58.479961
36.052173 4.496000 58.688818
35.905045 4.512000 58.897675
35.757638 4.528000 59.106532
35.609949 4.544000 59.315389
35.461977 4.560000 59.524246
35.313721 4.576000 59.733103
35.165178 4.592000 59.941960
35.016347 4.608000 60.150817
34.867227 4.624000 60.359674
34.717814 4.640000 60.568531
34.568109 4.656000 60.777388
34.418108 4.672000 60.986245
34.267810 4.688000 61.195102
34.117213 4.704000 61.403959
33.966315 4.720000 61.612816
33.815115 4.736000 61.821673
33.663610 4.752000 62.030530
33.511798 4.768000 62.239387
33.359678 4.784000 62.448244
33.207247 4.800000 62.657101
33.054503 4.816000 62.865958
32.901445 4.832000 63.074815
32.748071 4.848000 63.283672
32.594377 4.864000 63.492529
32.440362 4.880000 63.701386
32.286025 4.896000 63.910243
32.131362 4.912000 64.119100
31.976372 4.928000 64.327957
31.821052 4.944000 64.536814
31.665400 4.960000 64.745671
31.509414 4.976000 64.954528
31.353091 4.992000 65.163385
31.196429 5.008000 65.372242
31.039426 5.024000 65.581099
30.882079 5.040000 65.789956
30.724386 5.056000 65.998813
30.566345 5.072000 66.207670
30.407952 5.088000 66.416527
30.249205 5.104000 66.625384
30.090103 5.120000 66.834241
29.930641 5.136000 67.043098
29.770817 5.152000 67.251955
29.610629 5.168000 67.460812
29.450075 5.184000 67.669669
29.289150 5.200000 67.878526
29.127852 5.216000 68.087383
28.966179 5.232000 68.296240
28.804128 5.248000 68.505097
28.641695 5.264000 68.713954
28.478878 5.280000 68.922811
28.315673 5.296000 69.131668
28.152077 5.312000 69.340525
27.988088 5.328000 69.549382
27.823702 5.344000 69.758239
27.658915 5.360000 69.967096
27.493725 5.376000 70.175953
27.328128 5.392000 70.384810
27.162121 5.408000 70.593667
26.995699 5.424000 70.802524
26.828861 5.440000 71.011381
26.661601 5.456000 71.220238
26.493917 5.472000 71.429095
26.325804 5.488000 71.637952
26.157259 5.504000 71.846809
25.988277 5.520000 72.055666
25.818856 5.536000 72.264523
25.648991 5.552000 72.473380
25.478677 5.568000 72.682237
25.307910 5.584000 72.891094
25.136687 5.600000 73.099951
24.965003 5.616000 73.308808
24.792854 5.632000 73.517665
24.620234 5.648000 73.726522
24.447139 5.664000 73.935379
24.273565 5.680000 74.144236
24.099506 5.696000 74.353093
23.924958 5.712000 74.561950
23.749916 5.728000 74.770807
23.574374 5.744000 74.979664
23.398327 5.760000 75.188521
23.221770 5.776000 75.397378
23.044697 5.792000 75.606235
22.867102 5.808000 75.815092
22.688980 5.824000 76.023949
22.510324 5.840000 76.232806
22.331129 5.856000 76.441663
22.151388 5.872000 76.650520
21.971095 5.888000 76.859377
21.790243 5.904000 77.068234
21.608825 5.920000 77.277091
21.426835 5.936000 77.485948
21.244304 5.952000 77.694805
21.061263 5.968000 77.903662
20.877710 5.984000 78.112519
20.693642 6.000000 78.321376
20.509054 6.016000 78.530233
20.323942 6.032000 78.739090
20.138301 6.048000 78.947947
19.952129 6.064000 79.156804
19.765420 6.080000 79.365661
19.578169 6.096000 79.574518
19.390374 6.112000 79.783375
19.202028 6.128000 79.992232
19.013128 6.144000 80.201089
18.823669 6.160000 80.409946
18.633647 6.176000 80.618803
18.443055 6.192000 80.827660
18.251891 6.208000 81.036517
18.060149 6.224000 81.245374
17.867823 6.240000 81.454231
17.674910 6.256000 81.663088
17.481403 6.272000 81.871945
17.287299 6.288000 82.080802
17.092591 6.304000 82.289659
16.897274 6.320000 82.498516
16.701343 6.336000 82.707373
16.504793 6.352000 82.916230
16.467870 6.355000 82.955391
16.430925 6.358000 82.994551
16.393959 6.361000 83.033712
16.356970 6.364000 83.072873
16.319959 6.367000 83.112033
16.282926 6.370000 83.151194
16.245871 6.373000 83.190355
16.208794 6.376000 83.229515
16.171694 6.379000 83.268676
16.134572 6.382000 83.307837
16.097428 6.385000 83.346997
16.060261 6.388000 83.386158
16.023072 6.391000 83.425319
15.985860 6.394000 83.464480
15.948626 6.397000 83.503640
15.911370 6.400000 83.542801
15.874090 6.403000 83.581962
15.836789 6.406000 83.621122
15.799464 6.409000 83.660283
15.762117 6.412000 83.699444
15.724747 6.415000 83.738604
15.687355 6.418000 83.777765
15.649940 6.421000 83.816926
15.612501 6.424000 83.856086
15.575040 6.427000 83.895247
15.537556 6.430000 83.934408
15.500049 6.433000 83.973568
15.462519 6.436000 84.012729
15.424966 6.439000 84.051890
15.387390 6.442000 84.091051
15.349791 6.445000 84.130211
15.312169 6.448000 84.169372
15.274524 6.451000 84.208533
15.236855 6.454000 84.247693
15.199163 6.457000 84.286854
15.161448 6.460000 84.326015
15.123709 6.463000 84.365175
15.085947 6.466000 84.404336
15.048162 6.469000 84.443497
15.010353 6.472000 84.482657
14.972521 6.475000 84.521818
14.934665 6.478000 84.560979
14.896785 6.481000 84.600139
14.858882 6.484000 84.639300
14.820955 6.487000 84.678461
14.783005 6.490000 84.717622
14.745031 6.493000 84.756782
14.707033 6.496000 84.795943
14.669011 6.499000 84.835104
14.630965 6.502000 84.874264
14.592895 6.505000 84.913425
14.554802 6.508000 84.952586
14.516684 6.511000 84.991746
14.478543 6.514000 85.030907
14.440377 6.517000 85.070068
14.402187 6.520000 85.109228
14.363974 6.523000 85.148389
14.325736 6.526000 85.187550
14.287473 6.529000 85.226710
14.249187 6.532000 85.265871
14.210876 6.535000 85.305032
14.172540 6.538000 85.344193
14.134181 6.541000 85.383353
14.095797 6.544000 85.422514
14.057388 6.547000 85.461675
14.018955 6.550000 85.500835
13.980497 6.553000 85.539996
13.942015 6.556000 85.579157
13.903508 6.559000 85.618317
13.864977 6.562000 85.657478
13.826420 6.565000 85.696639
13.787839 6.568000 85.735799
13.749233 6.571000 85.774960
13.710602 6.574000 85.814121
13.671947 6.577000 85.853281
13.633266 6.580000 85.892442
13.594561 6.583000 85.931603
13.555830 6.586000 85.970764
13.517074 6.589000 86.009924
13.478293 6.592000 86.049085
13.439488 6.595000 86.088246
13.400656 6.598000 86.127406
13.361800 6.601000 86.166567
13.322919 6.604000 86.205728
13.284012 6.607000 86.244888
13.245079 6.610000 86.284049
13.206122 6.613000 86.323210
13.167139 6.616000 86.362370
13.128130 6.619000 86.401531
13.089096 6.622000 86.440692
13.050036 6.625000 86.479852
13.010951 6.628000 86.519013
12.971840 6.631000 86.558174
12.932704 6.634000 86.597335
12.893541 6.637000 86.636495
12.854353 6.640000 86.675656
12.815139 6.643000 86.714817
12.775900 6.646000 86.753977
12.736634 6.649000 86.793138
12.697343 6.652000 86.832299
12.658025 6.655000 86.871459
12.618682 6.658000 86.910620
12.579312 6.661000 86.949781
12.539917 6.664000 86.988941
12.500495 6.667000 87.028102
12.461047 6.670000 87.067263
12.421573 6.673000 87.106423
12.382073 6.676000 87.145584
12.342546 6.679000 87.184745
12.302993 6.682000 87.223906
12.263414 6.685000 87.263066
12.223808 6.688000 87.302227
12.184176 6.691000 87.341388
12.144517 6.694000 87.380548
12.104833 6.697000 87.419709
12.065127 6.700000 87.458870
12.025399 6.703000 87.498030
11.985650 6.706000 87.537191
11.945880 6.709000 87.576352
11.906089 6.712000 87.615512
11.866277 6.715000 87.654673
11.826445 6.718000 87.693834
11.786591 6.721000 87.732994
11.746717 6.724000 87.772155
11.706822 6.727000 87.811316
11.666907 6.730000 87.850477
11.626971 6.733000 87.889637
11.587014 6.736000 87.928798
11.547036 6.739000 87.967959
11.507038 6.742000 88.007119
11.467020 6.745000 88.046280
11.426981 6.748000 88.085441
11.386922 6.751000 88.124601
11.346842 6.754000 88.163762
11.306742 6.757000 88.202923
11.266622 6.760000 88.242083
11.226481 6.763000 88.281244
11.186320 6.766000 88.320405
11.146139 6.769000 88.359565
11.105938 6.772000 88.398726
11.065717 6.775000 88.437887
11.025476 6.778000 88.477048
10.985215 6.781000 88.516208
10.944934 6.784000 88.555369
10.904633 6.787000 88.594530
10.864313 6.790000 88.633690
10.823972 6.793000 88.672851
10.783612 6.796000 88.712012
10.743233 6.799000 88.751172
10.702834 6.802000 88.790333
10.662415 6.805000 88.829494
10.621977 6.808000 88.868654
10.581520 6.811000 88.907815
10.541044 6.814000 88.946976
10.500548 6.817000 88.986137
10.460034 6.820000 89.025297
10.419500 6.823000 89.064458
10.378948 6.826000 89.103619
10.338377 6.829000 89.142779
10.297787 6.832000 89.181940
10.257178 6.835000 89.221101
10.216551 6.838000 89.260261
10.175906 6.841000 89.299422
10.135242 6.844000 89.338583
10.094560 6.847000 89.377743
10.053860 6.850000 89.416904
10.013142 6.853000 89.456065
9.972406 6.856000 89.495225
9.931652 6.859000 89.534386
9.890881 6.862000 89.573547
9.850092 6.865000 89.612708
9.809286 6.868000 89.651868
9.768463 6.871000 89.691029
9.727622 6.874000 89.730190
9.686764 6.877000 89.769350
9.645890 6.880000 89.808511
9.604999 6.883000 89.847672
9.564091 6.886000 89.886832
9.523167 6.889000 89.925993
9.482227 6.892000 89.965154
9.441271 6.895000 90.004314
9.400298 6.898000 90.043475
9.359310 6.901000 90.082636
9.318307 6.904000 90.121796
9.277288 6.907000 90.160957
9.236254 6.910000 90.200118
9.195205 6.913000 90.239279
9.154141 6.916000 90.278439
9.113062 6.919000 90.317600
9.071970 6.922000 90.356761
9.030862 6.925000 90.395921
8.989741 6.928000 90.435082
8.948607 6.931000 90.474243
8.907458 6.934000 90.513403
8.866297 6.937000 90.552564
8.825122 6.940000 90.591725
8.783935 6.943000 90.630885
8.742735 6.946000 90.670046
8.701523 6.949000 90.709207
8.660299 6.952000 90.748367
8.619063 6.955000 90.787528
8.577815 6.958000 90.826689
8.536557 6.961000 90.865850
8.495287 6.964000 90.905010
8.454007 6.967000 90.944171
8.412717 6.970000 90.983332
8.371417 6.973000 91.022492
8.330107 6.976000 91.061653
8.288788 6.979000 91.100814
8.247460 6.982000 91.139974
8.206124 6.985000 91.179135
8.164779 6.988000 91.218296
8.123427 6.991000 91.257456
8.082067 6.994000 91.296617
8.040700 6.997000 91.335778
7.999326 7.000000 91.374938
7.957947 7.003000 91.414099
7.916561 7.006000 91.453260
7.875170 7.009000 91.492421
7.833774 7.012000 91.531581
7.792374 7.015000 91.570742
7.750969 7.018000 91.609903
7.709561 7.021000 91.649063
7.668151 7.024000 91.688224
7.626737 7.027000 91.727385
7.585322 7.030000 91.766545
7.543905 7.033000 91.805706
7.502487 7.036000 91.844867
7.461069 7.039000 91.884027
7.419651 7.042000 91.923188
7.378234 7.045000 91.962349
7.336819 7.048000 92.001509
7.295405 7.051000 92.040670
7.253994 7.054000 92.079831
7.212587 7.057000 92.118992
7.171183 7.060000 92.158152
7.129784 7.063000 92.197313
7.088390 7.066000 92.236474
7.047001 7.069000 92.275634
7.005598 7.072000 92.314795
6.964175 7.075000 92.353956
6.922733 7.078000 92.393116
6.881271 7.081000 92.432277
6.839788 7.084000 92.471438
6.798285 7.087000 92.510598
6.756762 7.090000 92.549759
6.715219 7.093000 92.588920
6.673656 7.096000 92.628080
6.632074 7.099000 92.667241
6.590474 7.102000 92.706402
6.548855 7.105000 92.745563
6.507218 7.108000 92.784723
6.465565 7.111000 92.823884
6.423894 7.114000 92.863045
6.382206 7.117000 92.902205
6.340503 7.120000 92.941366
6.298785 7.123000 92.980527
6.257051 7.126000 93.019687
6.215304 7.129000 93.058848
6.173542 7.132000 93.098009
6.131768 7.135000 93.137169
6.089981 7.138000 93.176330
6.048182 7.141000 93.215491
6.006373 7.144000 93.254651
5.964553 7.147000 93.293812
5.922723 7.150000 93.332973
5.880884 7.153000 93.372134
5.839038 7.156000 93.411294
5.797184 7.159000 93.450455
5.755323 7.162000 93.489616
5.713457 7.165000 93.528776
5.671586 7.168000 93.567937
5.629712 7.171000 93.607098
5.587834 7.174000 93.646258
5.545955 7.177000 93.685419
5.504075 7.180000 93.724580
5.462195 7.183000 93.763740
5.420317 7.186000 93.802901
5.378441 7.189000 93.842062
5.336569 7.192000 93.881222
5.294701 7.195000 93.920383
5.252840 7.198000 93.959544
5.210986 7.201000 93.998705
5.169140 7.204000 94.037865
5.127305 7.207000 94.077026
5.085481 7.210000 94.116187
5.043669 7.213000 94.155347
5.001872 7.216000 94.194508
4.960091 7.219000 94.233669
4.918328 7.222000 94.272829
4.876583 7.225000 94.311990
4.834859 7.228000 94.351151
4.793158 7.231000 94.390311
4.751481 7.234000 94.429472
4.709829 7.237000 94.468633
4.668206 7.240000 94.507794
4.626612 7.243000 94.546954
4.585051 7.246000 94.586115
4.543522 7.249000 94.625276
4.502030 7.252000 94.664436
4.460576 7.255000 94.703597
4.419162 7.258000 94.742758
4.377790 7.261000 94.781918
4.336463 7.264000 94.821079
4.295183 7.267000 94.860240
4.253952 7.270000 94.899400
4.212773 7.273000 94.938561
4.171649 7.276000 94.977722
4.130581 7.279000 95.016882
4.089574 7.282000 95.056043
4.048628 7.285000 95.095204
4.007748 7.288000 95.134365
3.966935 7.291000 95.173525
3.926194 7.294000 95.212686
3.885526 7.297000 95.251847
3.844935 7.300000 95.291007
3.804423 7.303000 95.330168
3.763995 7.306000 95.369329
3.723652 7.309000 95.408489
3.683399 7.312000 95.447650
3.643238 7.315000 95.486811
3.603173 7.318000 95.525971
3.563208 7.321000 95.565132
3.523345 7.324000 95.604293
3.483588 7.327000 95.643453
3.443942 7.330000 95.682614
3.404408 7.333000 95.721775
3.364992 7.336000 95.760936
3.325696 7.339000 95.800096
3.286524 7.342000 95.839257
3.247481 7.345000 95.878418
3.208570 7.348000 95.917578
3.169795 7.351000 95.956739
3.131159 7.354000 95.995900
3.092667 7.357000 96.035060
3.054322 7.360000 96.074221
3.016129 7.363000 96.113382
2.978092 7.366000 96.152542
2.940214 7.369000 96.191703
2.902499 7.372000 96.230864
2.864953 7.375000 96.270024
2.827577 7.378000 96.309185
2.790378 7.381000 96.348346
2.753358 7.384000 96.387507
2.716521 7.387000 96.426667
2.679873 7.390000 96.465828
2.643416 7.393000 96.504989
2.607155 7.396000 96.544149
2.571093 7.399000 96.583310
2.535236 7.402000 96.622471
2.499585 7.405000 96.661631
2.464147 7.408000 96.700792
2.428923 7.411000 96.739953
2.393919 7.414000 96.779113
2.359137 7.417000 96.818274
2.324582 7.420000 96.857435
2.290257 7.423000 96.896595
2.256165 7.426000 96.935756
2.222311 7.429000 96.974917
2.188697 7.432000 97.014078
2.155328 7.435000 97.053238
2.122205 7.438000 97.092399
2.089333 7.441000 97.131560
2.056714 7.444000 97.170720
2.024352 7.447000 97.209881
1.992249 7.450000 97.249042
1.960408 7.453000 97.288202
1.928831 7.456000 97.327363
1.897522 7.459000 97.366524
1.866483 7.462000 97.405684
1.835716 7.465000 97.444845
1.805223 7.468000 97.484006
1.775007 7.471000 97.523166
1.745069 7.474000 97.562327
1.715411 7.477000 97.601488
1.686035 7.480000 97.640649
1.656943 7.483000 97.679809
1.628136 7.486000 97.718970
1.599615 7.489000 97.758131
1.571382 7.492000 97.797291
1.543438 7.495000 97.836452
1.515783 7.498000 97.875613
1.488419 7.501000 97.914773
1.461346 7.504000 97.953934
1.434564 7.507000 97.993095
1.408075 7.510000 98.032255
1.381878 7.513000 98.071416
1.355974 7.516000 98.110577
1.330363 7.519000 98.149737
1.305043 7.522000 98.188898
1.280017 7.525000 98.228059
1.255282 7.528000 98.267220
1.230839 7.531000 98.306380
1.206687 7.534000 98.345541
1.182826 7.537000 98.384702
1.159254 7.540000 98.423862
1.135971 7.543000 98.463023
1.112975 7.546000 98.502184
1.090266 7.549000 98.541344
1.067843 7.552000 98.580505
1.045704 7.555000 98.619666
1.023847 7.558000 98.658826
1.002272 7.561000 98.697987
0.980977 7.564000 98.737148
0.959960 7.567000 98.776308
0.939219 7.570000 98.815469
0.918753 7.573000 98.854630
0.898560 7.576000 98.893791
0.878637 7.579000 98.932951
0.858984 7.582000 98.972112
0.839597 7.585000 99.011273
0.820475 7.588000 99.050433
0.801615 7.591000 99.089594
0.783016 7.594000 99.128755
0.764675 7.597000 99.167915
0.746589 7.600000 99.207076
0.728757 7.603000 99.246237
0.711176 7.606000 99.285397
0.693844 7.609000 99.324558
0.676757 7.612000 99.363719
0.659914 7.615000 99.402879
0.643313 7.618000 99.442040
0.626950 7.621000 99.481201
0.610823 7.624000 99.520362
0.594930 7.627000 99.559522
0.579267 7.630000 99.598683
0.563833 7.633000 99.637844
0.548624 7.636000 99.677004
0.533639 7.639000 99.716165
0.518873 7.642000 99.755326
0.504326 7.645000 99.794486
0.489994 7.648000 99.833647
0.475874 7.651000 99.872808
0.461964 7.654000 99.911968
0.448261 7.657000 99.951129
0.434763 7.660000 99.990290
0.421466 7.663000 100.029450
0.408355 7.666000 100.068611
0.395428 7.669000 100.107772
0.382683 7.672000 100.146933
0.370121 7.675000 100.186093
0.357740 7.678000 100.225254
0.345540 7.681000 100.264415
0.333521 7.684000 100.303575
0.321681 7.687000 100.342736
0.310020 7.690000 100.381897
0.298537 7.693000 100.421057
0.287232 7.696000 100.460218
0.276104 7.699000 100.499379
0.265152 7.702000 100.538539
0.254374 7.705000 100.577700
0.243770 7.708000 100.616861
0.233328 7.711000 100.656022
0.223056 7.714000 100.695182
0.212951 7.717000 100.734343
0.203013 7.720000 100.773504
0.193242 7.723000 100.812664
0.183635 7.726000 100.851825
0.174193 7.729000 100.890986
0.164914 7.732000 100.930146
0.155797 7.735000 100.969307
0.146840 7.738000 101.008468
0.138043 7.741000 101.047628
0.129403 7.744000 101.086789
0.120918 7.747000 101.125950
0.112585 7.750000 101.165110
0.104403 7.753000 101.204271
0.096367 7.756000 101.243432
0.088475 7.759000 101.282593
0.080720 7.762000 101.321753
0.073098 7.765000 101.360914
0.065602 7.768000 101.400075
0.058222 7.771000 101.439235
0.050947 7.774000 101.478396
0.043762 7.777000 101.517557
0.036647 7.780000 101.556717
0.029572 7.783000 101.595878
0.022495 7.786000 101.635039
0.015351 7.789000 101.674199
0.008040 7.792000 101.713360
0.000563 7.795000 101.752521

View File

@ -0,0 +1,522 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 70 MeV
70.000000 0.000000 0.000000
69.857849 0.020000 0.200813
69.715518 0.040000 0.401627
69.573006 0.060000 0.602440
69.430313 0.080000 0.803253
69.287438 0.100000 1.004067
69.144381 0.120000 1.204880
69.001140 0.140000 1.405693
68.857716 0.160000 1.606507
68.714106 0.180000 1.807320
68.570312 0.200000 2.008133
68.426331 0.220000 2.208947
68.282163 0.240000 2.409760
68.137807 0.260000 2.610573
67.993263 0.280000 2.811387
67.848530 0.300000 3.012200
67.703607 0.320000 3.213013
67.558494 0.340000 3.413827
67.413189 0.360000 3.614640
67.267692 0.380000 3.815453
67.122002 0.400000 4.016267
66.976118 0.420000 4.217080
66.830040 0.440000 4.417894
66.683767 0.460000 4.618707
66.537298 0.480000 4.819520
66.390631 0.500000 5.020334
66.243768 0.520000 5.221147
66.096705 0.540000 5.421960
65.949444 0.560000 5.622774
65.801982 0.580000 5.823587
65.654320 0.600000 6.024400
65.506455 0.620000 6.225214
65.358389 0.640000 6.426027
65.210118 0.660000 6.626840
65.061644 0.680000 6.827654
64.912964 0.700000 7.028467
64.764079 0.720000 7.229280
64.614987 0.740000 7.430094
64.465687 0.760000 7.630907
64.316178 0.780000 7.831720
64.166460 0.800000 8.032534
64.016532 0.820000 8.233347
63.866392 0.840000 8.434160
63.716041 0.860000 8.634974
63.565476 0.880000 8.835787
63.414698 0.900000 9.036600
63.263704 0.920000 9.237414
63.112495 0.940000 9.438227
62.961069 0.960000 9.639040
62.809425 0.980000 9.839854
62.657563 1.000000 10.040667
62.505481 1.020000 10.241480
62.353179 1.040000 10.442294
62.200655 1.060000 10.643107
62.047909 1.080000 10.843920
61.894939 1.100000 11.044734
61.741745 1.120000 11.245547
61.588325 1.140000 11.446360
61.434679 1.160000 11.647174
61.280806 1.180000 11.847987
61.126704 1.200000 12.048801
60.972372 1.220000 12.249614
60.817810 1.240000 12.450427
60.663016 1.260000 12.651241
60.507990 1.280000 12.852054
60.352730 1.300000 13.052867
60.197236 1.320000 13.253681
60.041505 1.340000 13.454494
59.885538 1.360000 13.655307
59.729332 1.380000 13.856121
59.572888 1.400000 14.056934
59.416203 1.420000 14.257747
59.259277 1.440000 14.458561
59.102109 1.460000 14.659374
58.944697 1.480000 14.860187
58.787040 1.500000 15.061001
58.629137 1.520000 15.261814
58.470987 1.540000 15.462627
58.312590 1.560000 15.663441
58.153942 1.580000 15.864254
57.995044 1.600000 16.065067
57.835895 1.620000 16.265881
57.676492 1.640000 16.466694
57.516835 1.660000 16.667507
57.356923 1.680000 16.868321
57.196754 1.700000 17.069134
57.036327 1.720000 17.269947
56.875641 1.740000 17.470761
56.714695 1.760000 17.671574
56.553486 1.780000 17.872387
56.392015 1.800000 18.073201
56.230280 1.820000 18.274014
56.068279 1.840000 18.474827
55.906010 1.860000 18.675641
55.743474 1.880000 18.876454
55.580668 1.900000 19.077267
55.417591 1.920000 19.278081
55.254242 1.940000 19.478894
55.090619 1.960000 19.679708
54.926721 1.980000 19.880521
54.762546 2.000000 20.081334
54.598094 2.020000 20.282148
54.433362 2.040000 20.482961
54.268349 2.060000 20.683774
54.103054 2.080000 20.884588
53.937475 2.100000 21.085401
53.771612 2.120000 21.286214
53.605461 2.140000 21.487028
53.439022 2.160000 21.687841
53.272294 2.180000 21.888654
53.105275 2.200000 22.089468
52.937962 2.220000 22.290281
52.770356 2.240000 22.491094
52.602453 2.260000 22.691908
52.434253 2.280000 22.892721
52.265754 2.300000 23.093534
52.096954 2.320000 23.294348
51.927852 2.340000 23.495161
51.758446 2.360000 23.695974
51.588735 2.380000 23.896788
51.418716 2.400000 24.097601
51.248388 2.420000 24.298414
51.077749 2.440000 24.499228
50.906799 2.460000 24.700041
50.735534 2.480000 24.900854
50.563953 2.500000 25.101668
50.392054 2.520000 25.302481
50.219836 2.540000 25.503294
50.047297 2.560000 25.704108
49.874434 2.580000 25.904921
49.701247 2.600000 26.105734
49.527733 2.620000 26.306548
49.353890 2.640000 26.507361
49.179717 2.660000 26.708174
49.005212 2.680000 26.908988
48.830372 2.700000 27.109801
48.655196 2.720000 27.310614
48.479681 2.740000 27.511428
48.303826 2.760000 27.712241
48.127629 2.780000 27.913055
47.951088 2.800000 28.113868
47.774200 2.820000 28.314681
47.596964 2.840000 28.515495
47.419378 2.860000 28.716308
47.241438 2.880000 28.917121
47.063144 2.900000 29.117935
46.884494 2.920000 29.318748
46.705484 2.940000 29.519561
46.526112 2.960000 29.720375
46.346378 2.980000 29.921188
46.166277 3.000000 30.122001
45.985809 3.020000 30.322815
45.804970 3.040000 30.523628
45.623759 3.060000 30.724441
45.442173 3.080000 30.925255
45.260209 3.100000 31.126068
45.077866 3.120000 31.326881
44.895140 3.140000 31.527695
44.712030 3.160000 31.728508
44.528533 3.180000 31.929321
44.344647 3.200000 32.130135
44.160368 3.220000 32.330948
43.975694 3.240000 32.531761
43.790624 3.260000 32.732575
43.605153 3.280000 32.933388
43.419280 3.300000 33.134201
43.233002 3.320000 33.335015
43.046316 3.340000 33.535828
42.859220 3.360000 33.736641
42.671710 3.380000 33.937455
42.483784 3.400000 34.138268
42.295439 3.420000 34.339081
42.106672 3.440000 34.539895
41.917480 3.460000 34.740708
41.727861 3.480000 34.941521
41.537811 3.500000 35.142335
41.347327 3.520000 35.343148
41.156407 3.540000 35.543962
40.965047 3.560000 35.744775
40.773244 3.580000 35.945588
40.580994 3.600000 36.146402
40.388296 3.620000 36.347215
40.195145 3.640000 36.548028
40.001538 3.660000 36.748842
39.807473 3.680000 36.949655
39.612944 3.700000 37.150468
39.417950 3.720000 37.351282
39.222487 3.740000 37.552095
39.026550 3.760000 37.752908
38.830138 3.780000 37.953722
38.633245 3.800000 38.154535
38.435869 3.820000 38.355348
38.238006 3.840000 38.556162
38.039651 3.860000 38.756975
37.840802 3.880000 38.957788
37.641454 3.900000 39.158602
37.441604 3.920000 39.359415
37.241247 3.940000 39.560228
37.040380 3.960000 39.761042
36.838999 3.980000 39.961855
36.637098 4.000000 40.162668
36.434675 4.020000 40.363482
36.231725 4.040000 40.564295
36.028244 4.060000 40.765108
35.824227 4.080000 40.965922
35.619669 4.100000 41.166735
35.414567 4.120000 41.367548
35.208916 4.140000 41.568362
35.002712 4.160000 41.769175
34.795948 4.180000 41.969988
34.588622 4.200000 42.170802
34.380727 4.220000 42.371615
34.172259 4.240000 42.572428
33.963213 4.260000 42.773242
33.753584 4.280000 42.974055
33.543366 4.300000 43.174869
33.332555 4.320000 43.375682
33.121145 4.340000 43.576495
32.909131 4.360000 43.777309
32.696507 4.380000 43.978122
32.483267 4.400000 44.178935
32.269406 4.420000 44.379749
32.054917 4.440000 44.580562
31.839796 4.460000 44.781375
31.624036 4.480000 44.982189
31.407630 4.500000 45.183002
31.190573 4.520000 45.383815
30.972858 4.540000 45.584629
30.754479 4.560000 45.785442
30.535429 4.580000 45.986255
30.315701 4.600000 46.187069
30.095289 4.620000 46.387882
29.874185 4.640000 46.588695
29.652382 4.660000 46.789509
29.429873 4.680000 46.990322
29.206650 4.700000 47.191135
28.982706 4.720000 47.391949
28.758033 4.740000 47.592762
28.532624 4.760000 47.793575
28.306469 4.780000 47.994389
28.079561 4.800000 48.195202
27.851891 4.820000 48.396015
27.623450 4.840000 48.596829
27.394230 4.860000 48.797642
27.164221 4.880000 48.998455
26.933415 4.900000 49.199269
26.701801 4.920000 49.400082
26.469370 4.940000 49.600895
26.236111 4.960000 49.801709
26.002015 4.980000 50.002522
25.767071 5.000000 50.203335
25.531267 5.020000 50.404149
25.294594 5.040000 50.604962
25.057039 5.060000 50.805775
24.818590 5.080000 51.006589
24.579236 5.100000 51.207402
24.338963 5.120000 51.408216
24.097760 5.140000 51.609029
23.855612 5.160000 51.809842
23.612507 5.180000 52.010656
23.368430 5.200000 52.211469
23.123366 5.220000 52.412282
22.877300 5.240000 52.613096
22.630217 5.260000 52.813909
22.382101 5.280000 53.014722
22.132935 5.300000 53.215536
21.882702 5.320000 53.416349
21.631383 5.340000 53.617162
21.378964 5.360000 53.817976
21.125522 5.380000 54.018789
20.871094 5.400000 54.219602
20.615669 5.420000 54.420416
20.359238 5.440000 54.621229
20.101788 5.460000 54.822042
19.843308 5.480000 55.022856
19.583786 5.500000 55.223669
19.323211 5.520000 55.424482
19.061571 5.540000 55.625296
18.798852 5.560000 55.826109
18.535043 5.580000 56.026922
18.270131 5.600000 56.227736
18.004102 5.620000 56.428549
17.736943 5.640000 56.629362
17.468642 5.660000 56.830176
17.199183 5.680000 57.030989
16.928552 5.700000 57.231802
16.656736 5.720000 57.432616
16.383720 5.740000 57.633429
16.109488 5.760000 57.834242
15.834026 5.780000 58.035056
15.557317 5.800000 58.235869
15.279346 5.820000 58.436682
15.000097 5.840000 58.637496
14.719554 5.860000 58.838309
14.437700 5.880000 59.039123
14.154518 5.900000 59.239936
13.869991 5.920000 59.440749
13.584102 5.940000 59.641563
13.296834 5.960000 59.842376
13.008170 5.980000 60.043189
12.718093 6.000000 60.244003
12.426586 6.020000 60.444816
12.133632 6.040000 60.645629
11.839358 6.060000 60.846443
11.543933 6.080000 61.047256
11.247374 6.100000 61.248069
10.949697 6.120000 61.448883
10.650923 6.140000 61.649696
10.351079 6.160000 61.850509
10.050198 6.180000 62.051323
9.748321 6.200000 62.252136
9.445499 6.220000 62.452949
9.141794 6.240000 62.653763
8.837280 6.260000 62.854576
8.532051 6.280000 63.055389
8.226217 6.300000 63.256203
7.919912 6.320000 63.457016
7.613301 6.340000 63.657829
7.306580 6.360000 63.858643
6.999956 6.380000 64.059456
6.692656 6.400000 64.260269
6.384289 6.420000 64.461083
6.075035 6.440000 64.661896
6.028585 6.443000 64.692018
5.982120 6.446000 64.722140
5.935643 6.449000 64.752262
5.889155 6.452000 64.782384
5.842655 6.455000 64.812506
5.796147 6.458000 64.842628
5.749629 6.461000 64.872750
5.703105 6.464000 64.902872
5.656575 6.467000 64.932994
5.610040 6.470000 64.963116
5.563502 6.473000 64.993238
5.516962 6.476000 65.023360
5.470421 6.479000 65.053482
5.423881 6.482000 65.083604
5.377344 6.485000 65.113726
5.330811 6.488000 65.143848
5.284284 6.491000 65.173970
5.237764 6.494000 65.204092
5.191254 6.497000 65.234214
5.144754 6.500000 65.264336
5.098268 6.503000 65.294458
5.051796 6.506000 65.324580
5.005342 6.509000 65.354702
4.958906 6.512000 65.384824
4.912492 6.515000 65.414946
4.866101 6.518000 65.445068
4.819736 6.521000 65.475190
4.773399 6.524000 65.505312
4.727092 6.527000 65.535434
4.680819 6.530000 65.565556
4.634581 6.533000 65.595678
4.588382 6.536000 65.625800
4.542224 6.539000 65.655922
4.496110 6.542000 65.686044
4.450042 6.545000 65.716166
4.404025 6.548000 65.746288
4.358061 6.551000 65.776410
4.312153 6.554000 65.806532
4.266305 6.557000 65.836654
4.220520 6.560000 65.866776
4.174800 6.563000 65.896898
4.129151 6.566000 65.927020
4.083576 6.569000 65.957142
4.038077 6.572000 65.987264
3.992660 6.575000 66.017386
3.947328 6.578000 66.047508
3.902084 6.581000 66.077630
3.856934 6.584000 66.107752
3.811881 6.587000 66.137874
3.766929 6.590000 66.167996
3.722084 6.593000 66.198118
3.677348 6.596000 66.228240
3.632728 6.599000 66.258362
3.588226 6.602000 66.288484
3.543849 6.605000 66.318606
3.499601 6.608000 66.348728
3.455487 6.611000 66.378850
3.411511 6.614000 66.408972
3.367679 6.617000 66.439094
3.323996 6.620000 66.469216
3.280466 6.623000 66.499338
3.237096 6.626000 66.529460
3.193890 6.629000 66.559582
3.150854 6.632000 66.589704
3.107992 6.635000 66.619826
3.065312 6.638000 66.649948
3.022817 6.641000 66.680070
2.980513 6.644000 66.710192
2.938406 6.647000 66.740314
2.896502 6.650000 66.770436
2.854806 6.653000 66.800558
2.813323 6.656000 66.830680
2.772059 6.659000 66.860802
2.731020 6.662000 66.890924
2.690211 6.665000 66.921046
2.649638 6.668000 66.951168
2.609306 6.671000 66.981290
2.569220 6.674000 67.011412
2.529387 6.677000 67.041534
2.489811 6.680000 67.071656
2.450499 6.683000 67.101778
2.411454 6.686000 67.131900
2.372682 6.689000 67.162022
2.334189 6.692000 67.192144
2.295980 6.695000 67.222266
2.258059 6.698000 67.252388
2.220430 6.701000 67.282510
2.183100 6.704000 67.312632
2.146072 6.707000 67.342754
2.109351 6.710000 67.372876
2.072941 6.713000 67.402998
2.036847 6.716000 67.433120
2.001072 6.719000 67.463242
1.965620 6.722000 67.493364
1.930495 6.725000 67.523486
1.895701 6.728000 67.553608
1.861240 6.731000 67.583730
1.827117 6.734000 67.613852
1.793334 6.737000 67.643974
1.759893 6.740000 67.674096
1.726798 6.743000 67.704218
1.694051 6.746000 67.734340
1.661655 6.749000 67.764462
1.629610 6.752000 67.794584
1.597920 6.755000 67.824706
1.566586 6.758000 67.854828
1.535608 6.761000 67.884950
1.504990 6.764000 67.915072
1.474730 6.767000 67.945194
1.444832 6.770000 67.975316
1.415294 6.773000 68.005438
1.386118 6.776000 68.035560
1.357303 6.779000 68.065682
1.328851 6.782000 68.095804
1.300760 6.785000 68.125926
1.273030 6.788000 68.156048
1.245661 6.791000 68.186170
1.218653 6.794000 68.216292
1.192004 6.797000 68.246414
1.165713 6.800000 68.276536
1.139779 6.803000 68.306658
1.114201 6.806000 68.336780
1.088978 6.809000 68.366902
1.064107 6.812000 68.397024
1.039587 6.815000 68.427146
1.015416 6.818000 68.457268
0.991592 6.821000 68.487390
0.968112 6.824000 68.517512
0.944975 6.827000 68.547634
0.922178 6.830000 68.577756
0.899717 6.833000 68.607878
0.877592 6.836000 68.638000
0.855799 6.839000 68.668122
0.834334 6.842000 68.698244
0.813196 6.845000 68.728366
0.792381 6.848000 68.758488
0.771886 6.851000 68.788610
0.751708 6.854000 68.818732
0.731843 6.857000 68.848854
0.712289 6.860000 68.878976
0.693042 6.863000 68.909098
0.674099 6.866000 68.939220
0.655456 6.869000 68.969342
0.637110 6.872000 68.999464
0.619057 6.875000 69.029586
0.601294 6.878000 69.059708
0.583817 6.881000 69.089830
0.566623 6.884000 69.119952
0.549707 6.887000 69.150074
0.533068 6.890000 69.180196
0.516700 6.893000 69.210318
0.500600 6.896000 69.240440
0.484765 6.899000 69.270562
0.469190 6.902000 69.300684
0.453873 6.905000 69.330806
0.438810 6.908000 69.360928
0.423996 6.911000 69.391050
0.409417 6.914000 69.421172
0.395060 6.917000 69.451294
0.380928 6.920000 69.481416
0.367019 6.923000 69.511538
0.353332 6.926000 69.541660
0.339867 6.929000 69.571782
0.326623 6.932000 69.601904
0.313599 6.935000 69.632026
0.300794 6.938000 69.662148
0.288207 6.941000 69.692270
0.275838 6.944000 69.722392
0.263685 6.947000 69.752514
0.251747 6.950000 69.782636
0.240019 6.953000 69.812758
0.228495 6.956000 69.842880
0.217180 6.959000 69.873002
0.206072 6.962000 69.903124
0.195169 6.965000 69.933246
0.184472 6.968000 69.963368
0.173979 6.971000 69.993490
0.163687 6.974000 70.023612
0.153596 6.977000 70.053734
0.143703 6.980000 70.083856
0.134007 6.983000 70.113978
0.124504 6.986000 70.144100
0.115191 6.989000 70.174222
0.106065 6.992000 70.204344
0.097122 6.995000 70.234466
0.088356 6.998000 70.264588
0.079761 7.001000 70.294710
0.071329 7.004000 70.324832
0.063049 7.007000 70.354954
0.054910 7.010000 70.385076
0.046892 7.013000 70.415198
0.038972 7.016000 70.445320
0.031114 7.019000 70.475442
0.023267 7.022000 70.505564
0.015345 7.025000 70.535686
0.007214 7.028000 70.565808
0.001641 7.030000 70.585890

View File

@ -0,0 +1,437 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 70 MeV
70.000000 0.000000 0.000000
69.841372 0.022000 0.205127
69.682520 0.044000 0.410255
69.523443 0.066000 0.615382
69.364141 0.088000 0.820510
69.204613 0.110000 1.025637
69.044857 0.132000 1.230764
68.884873 0.154000 1.435892
68.724660 0.176000 1.641019
68.564216 0.198000 1.846147
68.403541 0.220000 2.051274
68.242633 0.242000 2.256402
68.081492 0.264000 2.461529
67.920117 0.286000 2.666656
67.758506 0.308000 2.871784
67.596659 0.330000 3.076911
67.434574 0.352000 3.282039
67.272251 0.374000 3.487166
67.109688 0.396000 3.692293
66.946884 0.418000 3.897421
66.783838 0.440000 4.102548
66.620550 0.462000 4.307676
66.457017 0.484000 4.512803
66.293240 0.506000 4.717930
66.129216 0.528000 4.923058
65.964945 0.550000 5.128185
65.800425 0.572000 5.333313
65.635656 0.594000 5.538440
65.470636 0.616000 5.743568
65.305364 0.638000 5.948695
65.139839 0.660000 6.153822
64.974060 0.682000 6.358950
64.808026 0.704000 6.564077
64.641735 0.726000 6.769205
64.475186 0.748000 6.974332
64.308378 0.770000 7.179459
64.141310 0.792000 7.384587
63.973980 0.814000 7.589714
63.806388 0.836000 7.794842
63.638531 0.858000 7.999969
63.470410 0.880000 8.205097
63.302022 0.902000 8.410224
63.133366 0.924000 8.615351
62.964441 0.946000 8.820479
62.795246 0.968000 9.025606
62.625780 0.990000 9.230734
62.456040 1.012000 9.435861
62.286026 1.034000 9.640988
62.115736 1.056000 9.846116
61.945169 1.078000 10.051243
61.774324 1.100000 10.256371
61.603199 1.122000 10.461498
61.431793 1.144000 10.666625
61.260105 1.166000 10.871753
61.088132 1.188000 11.076880
60.915874 1.210000 11.282008
60.743330 1.232000 11.487135
60.570497 1.254000 11.692263
60.397374 1.276000 11.897390
60.223960 1.298000 12.102517
60.050254 1.320000 12.307645
59.876253 1.342000 12.512772
59.701957 1.364000 12.717900
59.527363 1.386000 12.923027
59.352471 1.408000 13.128154
59.177279 1.430000 13.333282
59.001785 1.452000 13.538409
58.825987 1.474000 13.743537
58.649884 1.496000 13.948664
58.473475 1.518000 14.153791
58.296757 1.540000 14.358919
58.119730 1.562000 14.564046
57.942391 1.584000 14.769174
57.764739 1.606000 14.974301
57.586772 1.628000 15.179429
57.408489 1.650000 15.384556
57.229888 1.672000 15.589683
57.050966 1.694000 15.794811
56.871723 1.716000 15.999938
56.692156 1.738000 16.205066
56.512264 1.760000 16.410193
56.332046 1.782000 16.615320
56.151498 1.804000 16.820448
55.970620 1.826000 17.025575
55.789409 1.848000 17.230703
55.607864 1.870000 17.435830
55.425983 1.892000 17.640958
55.243764 1.914000 17.846085
55.061205 1.936000 18.051212
54.878304 1.958000 18.256340
54.695059 1.980000 18.461467
54.511468 2.002000 18.666595
54.327530 2.024000 18.871722
54.143242 2.046000 19.076849
53.958602 2.068000 19.281977
53.773608 2.090000 19.487104
53.588259 2.112000 19.692232
53.402551 2.134000 19.897359
53.216484 2.156000 20.102486
53.030054 2.178000 20.307614
52.843260 2.200000 20.512741
52.656099 2.222000 20.717869
52.468570 2.244000 20.922996
52.280670 2.266000 21.128124
52.092397 2.288000 21.333251
51.903749 2.310000 21.538378
51.714723 2.332000 21.743506
51.525317 2.354000 21.948633
51.335529 2.376000 22.153761
51.145357 2.398000 22.358888
50.954797 2.420000 22.564015
50.763848 2.442000 22.769143
50.572508 2.464000 22.974270
50.380773 2.486000 23.179398
50.188642 2.508000 23.384525
49.996112 2.530000 23.589652
49.803180 2.552000 23.794780
49.609843 2.574000 23.999907
49.416101 2.596000 24.205035
49.221948 2.618000 24.410162
49.027384 2.640000 24.615290
48.832405 2.662000 24.820417
48.637009 2.684000 25.025544
48.441192 2.706000 25.230672
48.244953 2.728000 25.435799
48.048289 2.750000 25.640927
47.851195 2.772000 25.846054
47.653671 2.794000 26.051181
47.455713 2.816000 26.256309
47.257317 2.838000 26.461436
47.058482 2.860000 26.666564
46.859204 2.882000 26.871691
46.659479 2.904000 27.076819
46.459306 2.926000 27.281946
46.258681 2.948000 27.487073
46.057601 2.970000 27.692201
45.856062 2.992000 27.897328
45.654062 3.014000 28.102456
45.451597 3.036000 28.307583
45.248664 3.058000 28.512710
45.045260 3.080000 28.717838
44.841381 3.102000 28.922965
44.637024 3.124000 29.128093
44.432186 3.146000 29.333220
44.226863 3.168000 29.538347
44.021051 3.190000 29.743475
43.814748 3.212000 29.948602
43.607949 3.234000 30.153730
43.400650 3.256000 30.358857
43.192849 3.278000 30.563985
42.984541 3.300000 30.769112
42.775723 3.322000 30.974239
42.566391 3.344000 31.179367
42.356540 3.366000 31.384494
42.146167 3.388000 31.589622
41.935268 3.410000 31.794749
41.723839 3.432000 31.999876
41.511876 3.454000 32.205004
41.299375 3.476000 32.410131
41.086331 3.498000 32.615259
40.872740 3.520000 32.820386
40.658598 3.542000 33.025513
40.443900 3.564000 33.230641
40.228642 3.586000 33.435768
40.012820 3.608000 33.640896
39.796429 3.630000 33.846023
39.579465 3.652000 34.051151
39.361921 3.674000 34.256278
39.143795 3.696000 34.461405
38.925081 3.718000 34.666533
38.705774 3.740000 34.871660
38.485868 3.762000 35.076788
38.265360 3.784000 35.281915
38.044244 3.806000 35.487042
37.822515 3.828000 35.692170
37.600167 3.850000 35.897297
37.377195 3.872000 36.102425
37.153593 3.894000 36.307552
36.929357 3.916000 36.512679
36.704480 3.938000 36.717807
36.478957 3.960000 36.922934
36.252781 3.982000 37.128062
36.025948 4.004000 37.333189
35.798451 4.026000 37.538317
35.570283 4.048000 37.743444
35.341439 4.070000 37.948571
35.111913 4.092000 38.153699
34.881697 4.114000 38.358826
34.650786 4.136000 38.563954
34.419172 4.158000 38.769081
34.186849 4.180000 38.974208
33.953811 4.202000 39.179336
33.720050 4.224000 39.384463
33.485558 4.246000 39.589591
33.250329 4.268000 39.794718
33.014356 4.290000 39.999846
32.777630 4.312000 40.204973
32.540144 4.334000 40.410100
32.301891 4.356000 40.615228
32.062862 4.378000 40.820355
31.823048 4.400000 41.025483
31.582443 4.422000 41.230610
31.341037 4.444000 41.435737
31.098821 4.466000 41.640865
30.855787 4.488000 41.845992
30.611926 4.510000 42.051120
30.367229 4.532000 42.256247
30.121685 4.554000 42.461374
29.875286 4.576000 42.666502
29.628022 4.598000 42.871629
29.379882 4.620000 43.076757
29.130857 4.642000 43.281884
28.880935 4.664000 43.487012
28.630106 4.686000 43.692139
28.378359 4.708000 43.897266
28.125683 4.730000 44.102394
27.872066 4.752000 44.307521
27.617495 4.774000 44.512649
27.361959 4.796000 44.717776
27.105446 4.818000 44.922903
26.847942 4.840000 45.128031
26.589434 4.862000 45.333158
26.329908 4.884000 45.538286
26.069351 4.906000 45.743413
25.807748 4.928000 45.948540
25.545084 4.950000 46.153668
25.281345 4.972000 46.358795
25.016513 4.994000 46.563923
24.750574 5.016000 46.769050
24.483509 5.038000 46.974178
24.215303 5.060000 47.179305
23.945936 5.082000 47.384432
23.675391 5.104000 47.589560
23.403648 5.126000 47.794687
23.130687 5.148000 47.999815
22.856488 5.170000 48.204942
22.581029 5.192000 48.410069
22.304289 5.214000 48.615197
22.026243 5.236000 48.820324
21.746868 5.258000 49.025452
21.466139 5.280000 49.230579
21.184098 5.302000 49.435707
20.900838 5.324000 49.640834
20.616348 5.346000 49.845961
20.330613 5.368000 50.051089
20.043619 5.390000 50.256216
19.755348 5.412000 50.461344
19.465786 5.434000 50.666471
19.174915 5.456000 50.871598
18.882719 5.478000 51.076726
18.589182 5.500000 51.281853
18.294285 5.522000 51.486981
17.998011 5.544000 51.692108
17.700342 5.566000 51.897235
17.401259 5.588000 52.102363
17.100743 5.610000 52.307490
16.798774 5.632000 52.512618
16.495334 5.654000 52.717745
16.190401 5.676000 52.922873
15.883955 5.698000 53.128000
15.575976 5.720000 53.333127
15.266441 5.742000 53.538255
14.955328 5.764000 53.743382
14.642617 5.786000 53.948510
14.328283 5.808000 54.153637
14.012303 5.830000 54.358764
13.694656 5.852000 54.563892
13.375318 5.874000 54.769019
13.054265 5.896000 54.974147
12.731474 5.918000 55.179274
12.406923 5.940000 55.384401
12.080593 5.962000 55.589529
11.752694 5.984000 55.794656
11.423386 6.006000 55.999784
11.092692 6.028000 56.204911
10.760639 6.050000 56.410039
10.427259 6.072000 56.615166
10.092597 6.094000 56.820293
9.756708 6.116000 57.025421
9.419660 6.138000 57.230548
9.081540 6.160000 57.435676
8.742456 6.182000 57.640803
8.402540 6.204000 57.845930
8.061959 6.226000 58.051058
7.720917 6.248000 58.256185
7.379664 6.270000 58.461313
7.038508 6.292000 58.666440
6.696734 6.314000 58.871567
6.353665 6.336000 59.076695
6.009547 6.358000 59.281822
5.946893 6.362000 59.319118
5.884218 6.366000 59.356414
5.821525 6.370000 59.393710
5.758816 6.374000 59.431006
5.696094 6.378000 59.468302
5.633363 6.382000 59.505598
5.570625 6.386000 59.542894
5.507884 6.390000 59.580189
5.445143 6.394000 59.617485
5.382406 6.398000 59.654781
5.319676 6.402000 59.692077
5.256959 6.406000 59.729373
5.194258 6.410000 59.766669
5.131578 6.414000 59.803965
5.068922 6.418000 59.841261
5.006297 6.422000 59.878557
4.943707 6.426000 59.915853
4.881157 6.430000 59.953148
4.818653 6.434000 59.990444
4.756202 6.438000 60.027740
4.693808 6.442000 60.065036
4.631478 6.446000 60.102332
4.569218 6.450000 60.139628
4.507036 6.454000 60.176924
4.444939 6.458000 60.214220
4.382934 6.462000 60.251516
4.321028 6.466000 60.288811
4.259229 6.470000 60.326107
4.197546 6.474000 60.363403
4.135987 6.478000 60.400699
4.074562 6.482000 60.437995
4.013278 6.486000 60.475291
3.952146 6.490000 60.512587
3.891174 6.494000 60.549883
3.830374 6.498000 60.587179
3.769756 6.502000 60.624474
3.709329 6.506000 60.661770
3.649105 6.510000 60.699066
3.589095 6.514000 60.736362
3.529311 6.518000 60.773658
3.469763 6.522000 60.810954
3.410465 6.526000 60.848250
3.351428 6.530000 60.885546
3.292664 6.534000 60.922842
3.234187 6.538000 60.960138
3.176008 6.542000 60.997433
3.118142 6.546000 61.034729
3.060600 6.550000 61.072025
3.003398 6.554000 61.109321
2.946547 6.558000 61.146617
2.890061 6.562000 61.183913
2.833954 6.566000 61.221209
2.778240 6.570000 61.258505
2.722932 6.574000 61.295801
2.668043 6.578000 61.333096
2.613588 6.582000 61.370392
2.559579 6.586000 61.407688
2.506030 6.590000 61.444984
2.452953 6.594000 61.482280
2.400363 6.598000 61.519576
2.348271 6.602000 61.556872
2.296689 6.606000 61.594168
2.245630 6.610000 61.631464
2.195106 6.614000 61.668759
2.145128 6.618000 61.706055
2.095707 6.622000 61.743351
2.046853 6.626000 61.780647
1.998577 6.630000 61.817943
1.950887 6.634000 61.855239
1.903793 6.638000 61.892535
1.857304 6.642000 61.929831
1.811427 6.646000 61.967127
1.766169 6.650000 62.004423
1.721537 6.654000 62.041718
1.677538 6.658000 62.079014
1.634176 6.662000 62.116310
1.591456 6.666000 62.153606
1.549383 6.670000 62.190902
1.507959 6.674000 62.228198
1.467188 6.678000 62.265494
1.427071 6.682000 62.302790
1.387610 6.686000 62.340086
1.348806 6.690000 62.377381
1.310659 6.694000 62.414677
1.273169 6.698000 62.451973
1.236334 6.702000 62.489269
1.200152 6.706000 62.526565
1.164622 6.710000 62.563861
1.129741 6.714000 62.601157
1.095505 6.718000 62.638453
1.061910 6.722000 62.675749
1.028953 6.726000 62.713045
0.996628 6.730000 62.750340
0.964930 6.734000 62.787636
0.933854 6.738000 62.824932
0.903393 6.742000 62.862228
0.873542 6.746000 62.899524
0.844293 6.750000 62.936820
0.815640 6.754000 62.974116
0.787575 6.758000 63.011412
0.760090 6.762000 63.048708
0.733179 6.766000 63.086003
0.706832 6.770000 63.123299
0.681042 6.774000 63.160595
0.655801 6.778000 63.197891
0.631100 6.782000 63.235187
0.606930 6.786000 63.272483
0.583283 6.790000 63.309779
0.560151 6.794000 63.347075
0.537523 6.798000 63.384371
0.515393 6.802000 63.421666
0.493750 6.806000 63.458962
0.472585 6.810000 63.496258
0.451890 6.814000 63.533554
0.431656 6.818000 63.570850
0.411866 6.822000 63.608146
0.392488 6.826000 63.645442
0.373520 6.830000 63.682738
0.354960 6.834000 63.720034
0.336806 6.838000 63.757330
0.319056 6.842000 63.794625
0.301707 6.846000 63.831921
0.284758 6.850000 63.869217
0.268205 6.854000 63.906513
0.252045 6.858000 63.943809
0.236267 6.862000 63.981105
0.220864 6.866000 64.018401
0.205837 6.870000 64.055697
0.191183 6.874000 64.092993
0.176901 6.878000 64.130288
0.162985 6.882000 64.167584
0.149432 6.886000 64.204880
0.136237 6.890000 64.242176
0.123395 6.894000 64.279472
0.110897 6.898000 64.316768
0.098734 6.902000 64.354064
0.086895 6.906000 64.391360
0.075365 6.910000 64.428656
0.064120 6.914000 64.465951
0.053133 6.918000 64.503247
0.042359 6.922000 64.540543
0.031728 6.926000 64.577839
0.021125 6.930000 64.615135
0.010329 6.934000 64.652431
0.000000 6.938000 64.689727

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,641 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 70 MeV
70.000000 0.000000 0.000000
69.888959 0.020000 0.200813
69.777801 0.040000 0.401627
69.666527 0.060000 0.602440
69.555135 0.080000 0.803253
69.443625 0.100000 1.004067
69.331997 0.120000 1.204880
69.220251 0.140000 1.405693
69.108386 0.160000 1.606507
68.996402 0.180000 1.807320
68.884299 0.200000 2.008133
68.772075 0.220000 2.208947
68.659731 0.240000 2.409760
68.547267 0.260000 2.610573
68.434681 0.280000 2.811387
68.321974 0.300000 3.012200
68.209144 0.320000 3.213013
68.096193 0.340000 3.413827
67.983119 0.360000 3.614640
67.869921 0.380000 3.815453
67.756600 0.400000 4.016267
67.643156 0.420000 4.217080
67.529586 0.440000 4.417894
67.415892 0.460000 4.618707
67.302073 0.480000 4.819520
67.188129 0.500000 5.020334
67.074058 0.520000 5.221147
66.959861 0.540000 5.421960
66.845537 0.560000 5.622774
66.731086 0.580000 5.823587
66.616507 0.600000 6.024400
66.501799 0.620000 6.225214
66.386964 0.640000 6.426027
66.271999 0.660000 6.626840
66.156905 0.680000 6.827654
66.041681 0.700000 7.028467
65.926327 0.720000 7.229280
65.810842 0.740000 7.430094
65.695225 0.760000 7.630907
65.579477 0.780000 7.831720
65.463597 0.800000 8.032534
65.347584 0.820000 8.233347
65.231439 0.840000 8.434160
65.115159 0.860000 8.634974
64.998746 0.880000 8.835787
64.882198 0.900000 9.036600
64.765516 0.920000 9.237414
64.648698 0.940000 9.438227
64.531744 0.960000 9.639040
64.414654 0.980000 9.839854
64.297427 1.000000 10.040667
64.180063 1.020000 10.241480
64.062561 1.040000 10.442294
63.944921 1.060000 10.643107
63.827142 1.080000 10.843920
63.709223 1.100000 11.044734
63.591165 1.120000 11.245547
63.472967 1.140000 11.446360
63.354628 1.160000 11.647174
63.236148 1.180000 11.847987
63.117526 1.200000 12.048801
62.998761 1.220000 12.249614
62.879854 1.240000 12.450427
62.760804 1.260000 12.651241
62.641610 1.280000 12.852054
62.522271 1.300000 13.052867
62.402787 1.320000 13.253681
62.283158 1.340000 13.454494
62.163383 1.360000 13.655307
62.043462 1.380000 13.856121
61.923393 1.400000 14.056934
61.803177 1.420000 14.257747
61.682813 1.440000 14.458561
61.562300 1.460000 14.659374
61.441638 1.480000 14.860187
61.320826 1.500000 15.061001
61.199864 1.520000 15.261814
61.078751 1.540000 15.462627
60.957486 1.560000 15.663441
60.836069 1.580000 15.864254
60.714500 1.600000 16.065067
60.592777 1.620000 16.265881
60.470901 1.640000 16.466694
60.348870 1.660000 16.667507
60.226684 1.680000 16.868321
60.104342 1.700000 17.069134
59.981845 1.720000 17.269947
59.859190 1.740000 17.470761
59.736379 1.760000 17.671574
59.613409 1.780000 17.872387
59.490281 1.800000 18.073201
59.366993 1.820000 18.274014
59.243545 1.840000 18.474827
59.119937 1.860000 18.675641
58.996168 1.880000 18.876454
58.872238 1.900000 19.077267
58.748144 1.920000 19.278081
58.623888 1.940000 19.478894
58.499468 1.960000 19.679708
58.374884 1.980000 19.880521
58.250135 2.000000 20.081334
58.125220 2.020000 20.282148
58.000139 2.040000 20.482961
57.874891 2.060000 20.683774
57.749475 2.080000 20.884588
57.623891 2.100000 21.085401
57.498138 2.120000 21.286214
57.372215 2.140000 21.487028
57.246122 2.160000 21.687841
57.119858 2.180000 21.888654
56.993422 2.200000 22.089468
56.866813 2.220000 22.290281
56.740031 2.240000 22.491094
56.613076 2.260000 22.691908
56.485945 2.280000 22.892721
56.358640 2.300000 23.093534
56.231158 2.320000 23.294348
56.103499 2.340000 23.495161
55.975663 2.360000 23.695974
55.847649 2.380000 23.896788
55.719455 2.400000 24.097601
55.591082 2.420000 24.298414
55.462528 2.440000 24.499228
55.333793 2.460000 24.700041
55.204875 2.480000 24.900854
55.075775 2.500000 25.101668
54.946491 2.520000 25.302481
54.817022 2.540000 25.503294
54.687369 2.560000 25.704108
54.557529 2.580000 25.904921
54.427502 2.600000 26.105734
54.297288 2.620000 26.306548
54.166885 2.640000 26.507361
54.036293 2.660000 26.708174
53.905510 2.680000 26.908988
53.774537 2.700000 27.109801
53.643371 2.720000 27.310614
53.512013 2.740000 27.511428
53.380462 2.760000 27.712241
53.248716 2.780000 27.913055
53.116775 2.800000 28.113868
52.984637 2.820000 28.314681
52.852303 2.840000 28.515495
52.719771 2.860000 28.716308
52.587040 2.880000 28.917121
52.454109 2.900000 29.117935
52.320977 2.920000 29.318748
52.187644 2.940000 29.519561
52.054109 2.960000 29.720375
51.920370 2.980000 29.921188
51.786427 3.000000 30.122001
51.652278 3.020000 30.322815
51.517923 3.040000 30.523628
51.383362 3.060000 30.724441
51.248592 3.080000 30.925255
51.113612 3.100000 31.126068
50.978423 3.120000 31.326881
50.843023 3.140000 31.527695
50.707411 3.160000 31.728508
50.571585 3.180000 31.929321
50.435546 3.200000 32.130135
50.299291 3.220000 32.330948
50.162820 3.240000 32.531761
50.026132 3.260000 32.732575
49.889226 3.280000 32.933388
49.752100 3.300000 33.134201
49.614755 3.320000 33.335015
49.477187 3.340000 33.535828
49.339398 3.360000 33.736641
49.201384 3.380000 33.937455
49.063146 3.400000 34.138268
48.924683 3.420000 34.339081
48.785992 3.440000 34.539895
48.647074 3.460000 34.740708
48.507926 3.480000 34.941521
48.368548 3.500000 35.142335
48.228938 3.520000 35.343148
48.089096 3.540000 35.543962
47.949020 3.560000 35.744775
47.808709 3.580000 35.945588
47.668162 3.600000 36.146402
47.527378 3.620000 36.347215
47.386355 3.640000 36.548028
47.245093 3.660000 36.748842
47.103589 3.680000 36.949655
46.961843 3.700000 37.150468
46.819854 3.720000 37.351282
46.677619 3.740000 37.552095
46.535139 3.760000 37.752908
46.392411 3.780000 37.953722
46.249435 3.800000 38.154535
46.106209 3.820000 38.355348
45.962731 3.840000 38.556162
45.819001 3.860000 38.756975
45.675017 3.880000 38.957788
45.530778 3.900000 39.158602
45.386282 3.920000 39.359415
45.241528 3.940000 39.560228
45.096514 3.960000 39.761042
44.951240 3.980000 39.961855
44.805703 4.000000 40.162668
44.659903 4.020000 40.363482
44.513837 4.040000 40.564295
44.367505 4.060000 40.765108
44.220904 4.080000 40.965922
44.074034 4.100000 41.166735
43.926893 4.120000 41.367548
43.779480 4.140000 41.568362
43.631792 4.160000 41.769175
43.483829 4.180000 41.969988
43.335588 4.200000 42.170802
43.187068 4.220000 42.371615
43.038268 4.240000 42.572428
42.889186 4.260000 42.773242
42.739821 4.280000 42.974055
42.590170 4.300000 43.174869
42.440232 4.320000 43.375682
42.290006 4.340000 43.576495
42.139489 4.360000 43.777309
41.988680 4.380000 43.978122
41.837578 4.400000 44.178935
41.686180 4.420000 44.379749
41.534485 4.440000 44.580562
41.382491 4.460000 44.781375
41.230196 4.480000 44.982189
41.077599 4.500000 45.183002
40.924698 4.520000 45.383815
40.771490 4.540000 45.584629
40.617974 4.560000 45.785442
40.464148 4.580000 45.986255
40.310010 4.600000 46.187069
40.155558 4.620000 46.387882
40.000791 4.640000 46.588695
39.845705 4.660000 46.789509
39.690301 4.680000 46.990322
39.534574 4.700000 47.191135
39.378524 4.720000 47.391949
39.222148 4.740000 47.592762
39.065444 4.760000 47.793575
38.908410 4.780000 47.994389
38.751044 4.800000 48.195202
38.593343 4.820000 48.396015
38.435307 4.840000 48.596829
38.276931 4.860000 48.797642
38.118215 4.880000 48.998455
37.959156 4.900000 49.199269
37.799752 4.920000 49.400082
37.640000 4.940000 49.600895
37.479898 4.960000 49.801709
37.319444 4.980000 50.002522
37.158635 5.000000 50.203335
36.997469 5.020000 50.404149
36.835944 5.040000 50.604962
36.674057 5.060000 50.805775
36.511805 5.080000 51.006589
36.349187 5.100000 51.207402
36.186199 5.120000 51.408216
36.022839 5.140000 51.609029
35.859104 5.160000 51.809842
35.694992 5.180000 52.010656
35.530500 5.200000 52.211469
35.365626 5.220000 52.412282
35.200366 5.240000 52.613096
35.034718 5.260000 52.813909
34.868678 5.280000 53.014722
34.702245 5.300000 53.215536
34.535416 5.320000 53.416349
34.368186 5.340000 53.617162
34.200554 5.360000 53.817976
34.032516 5.380000 54.018789
33.864070 5.400000 54.219602
33.695212 5.420000 54.420416
33.525939 5.440000 54.621229
33.356248 5.460000 54.822042
33.186136 5.480000 55.022856
33.015599 5.500000 55.223669
32.844635 5.520000 55.424482
32.673239 5.540000 55.625296
32.501409 5.560000 55.826109
32.329141 5.580000 56.026922
32.156432 5.600000 56.227736
31.983278 5.620000 56.428549
31.809675 5.640000 56.629362
31.635620 5.660000 56.830176
31.461109 5.680000 57.030989
31.286138 5.700000 57.231802
31.110704 5.720000 57.432616
30.934803 5.740000 57.633429
30.758431 5.760000 57.834242
30.581583 5.780000 58.035056
30.404256 5.800000 58.235869
30.226446 5.820000 58.436682
30.048148 5.840000 58.637496
29.869358 5.860000 58.838309
29.690072 5.880000 59.039123
29.510286 5.900000 59.239936
29.329995 5.920000 59.440749
29.149194 5.940000 59.641563
28.967880 5.960000 59.842376
28.786046 5.980000 60.043189
28.603689 6.000000 60.244003
28.420804 6.020000 60.444816
28.237385 6.040000 60.645629
28.053428 6.060000 60.846443
27.868928 6.080000 61.047256
27.683879 6.100000 61.248069
27.498275 6.120000 61.448883
27.312113 6.140000 61.649696
27.125386 6.160000 61.850509
26.938088 6.180000 62.051323
26.750214 6.200000 62.252136
26.561758 6.220000 62.452949
26.372713 6.240000 62.653763
26.183075 6.260000 62.854576
25.992837 6.280000 63.055389
25.801992 6.300000 63.256203
25.610533 6.320000 63.457016
25.418456 6.340000 63.657829
25.225751 6.360000 63.858643
25.032414 6.380000 64.059456
24.838436 6.400000 64.260269
24.643810 6.420000 64.461083
24.448530 6.440000 64.661896
24.252587 6.460000 64.862709
24.055974 6.480000 65.063523
23.858683 6.500000 65.264336
23.660706 6.520000 65.465149
23.462034 6.540000 65.665963
23.262659 6.560000 65.866776
23.062573 6.580000 66.067589
22.861766 6.600000 66.268403
22.660228 6.620000 66.469216
22.457952 6.640000 66.670030
22.254926 6.660000 66.870843
22.051142 6.680000 67.071656
21.846588 6.700000 67.272470
21.641254 6.720000 67.473283
21.435130 6.740000 67.674096
21.228203 6.760000 67.874910
21.020463 6.780000 68.075723
20.811898 6.800000 68.276536
20.602495 6.820000 68.477350
20.392241 6.840000 68.678163
20.181124 6.860000 68.878976
19.969160 6.880000 69.079790
19.756400 6.900000 69.280603
19.542839 6.920000 69.481416
19.328469 6.940000 69.682230
19.113279 6.960000 69.883043
18.897261 6.980000 70.083856
18.680406 7.000000 70.284670
18.462704 7.020000 70.485483
18.244145 7.040000 70.686296
18.024719 7.060000 70.887110
17.804417 7.080000 71.087923
17.583227 7.100000 71.288736
17.361140 7.120000 71.489550
17.138144 7.140000 71.690363
16.914229 7.160000 71.891176
16.689383 7.180000 72.091990
16.463594 7.200000 72.292803
16.236852 7.220000 72.493616
16.009144 7.240000 72.694430
15.780457 7.260000 72.895243
15.550780 7.280000 73.096056
15.320099 7.300000 73.296870
15.088401 7.320000 73.497683
14.855673 7.340000 73.698496
14.621902 7.360000 73.899310
14.387072 7.380000 74.100123
14.151170 7.400000 74.300936
13.914181 7.420000 74.501750
13.676091 7.440000 74.702563
13.436883 7.460000 74.903377
13.196543 7.480000 75.104190
12.955055 7.500000 75.305003
12.712402 7.520000 75.505817
12.468568 7.540000 75.706630
12.223537 7.560000 75.907443
11.977292 7.580000 76.108257
11.729816 7.600000 76.309070
11.481093 7.620000 76.509883
11.231106 7.640000 76.710697
10.979893 7.660000 76.911510
10.727574 7.680000 77.112323
10.474158 7.700000 77.313137
10.219647 7.720000 77.513950
9.964046 7.740000 77.714763
9.707363 7.760000 77.915577
9.449611 7.780000 78.116390
9.190804 7.800000 78.317203
8.930967 7.820000 78.518017
8.670126 7.840000 78.718830
8.408319 7.860000 78.919643
8.145592 7.880000 79.120457
7.882002 7.900000 79.321270
7.617622 7.920000 79.522083
7.352540 7.940000 79.722897
7.312723 7.943000 79.753019
7.272893 7.946000 79.783141
7.233051 7.949000 79.813263
7.193197 7.952000 79.843385
7.153331 7.955000 79.873507
7.113454 7.958000 79.903629
7.073566 7.961000 79.933751
7.033665 7.964000 79.963873
6.993735 7.967000 79.993995
6.953774 7.970000 80.024117
6.913782 7.973000 80.054239
6.873759 7.976000 80.084361
6.833704 7.979000 80.114483
6.793617 7.982000 80.144605
6.753498 7.985000 80.174727
6.713347 7.988000 80.204849
6.673166 7.991000 80.234971
6.632953 7.994000 80.265093
6.592709 7.997000 80.295215
6.552434 8.000000 80.325337
6.512129 8.003000 80.355459
6.471793 8.006000 80.385581
6.431427 8.009000 80.415703
6.391032 8.012000 80.445825
6.350607 8.015000 80.475947
6.310152 8.018000 80.506069
6.269669 8.021000 80.536191
6.229157 8.024000 80.566313
6.188617 8.027000 80.596435
6.148049 8.030000 80.626557
6.107453 8.033000 80.656679
6.066830 8.036000 80.686801
6.026181 8.039000 80.716923
5.985505 8.042000 80.747045
5.944803 8.045000 80.777167
5.904076 8.048000 80.807289
5.863323 8.051000 80.837411
5.822547 8.054000 80.867533
5.781746 8.057000 80.897655
5.740923 8.060000 80.927777
5.700076 8.063000 80.957899
5.659208 8.066000 80.988021
5.618318 8.069000 81.018143
5.577407 8.072000 81.048265
5.536476 8.075000 81.078387
5.495525 8.078000 81.108509
5.454556 8.081000 81.138631
5.413569 8.084000 81.168753
5.372565 8.087000 81.198875
5.331545 8.090000 81.228997
5.290509 8.093000 81.259119
5.249459 8.096000 81.289241
5.208395 8.099000 81.319363
5.167319 8.102000 81.349485
5.126232 8.105000 81.379607
5.085134 8.108000 81.409729
5.044026 8.111000 81.439851
5.002911 8.114000 81.469973
4.961788 8.117000 81.500095
4.920660 8.120000 81.530217
4.879527 8.123000 81.560339
4.838391 8.126000 81.590461
4.797254 8.129000 81.620583
4.756115 8.132000 81.650705
4.714978 8.135000 81.680827
4.673844 8.138000 81.710949
4.632713 8.141000 81.741071
4.591588 8.144000 81.771193
4.550471 8.147000 81.801315
4.509363 8.150000 81.831437
4.468266 8.153000 81.861559
4.427181 8.156000 81.891681
4.386112 8.159000 81.921803
4.345058 8.162000 81.951925
4.304024 8.165000 81.982047
4.263010 8.168000 82.012169
4.222020 8.171000 82.042291
4.181054 8.174000 82.072413
4.140116 8.177000 82.102535
4.099207 8.180000 82.132657
4.058331 8.183000 82.162779
4.017489 8.186000 82.192901
3.976685 8.189000 82.223023
3.935920 8.192000 82.253145
3.895198 8.195000 82.283267
3.854522 8.198000 82.313389
3.813893 8.201000 82.343511
3.773316 8.204000 82.373633
3.732793 8.207000 82.403755
3.692327 8.210000 82.433877
3.651921 8.213000 82.463999
3.611579 8.216000 82.494121
3.571303 8.219000 82.524243
3.531098 8.222000 82.554365
3.490967 8.225000 82.584487
3.450912 8.228000 82.614609
3.410939 8.231000 82.644731
3.371050 8.234000 82.674853
3.331249 8.237000 82.704975
3.291540 8.240000 82.735097
3.251927 8.243000 82.765219
3.212413 8.246000 82.795341
3.173004 8.249000 82.825463
3.133702 8.252000 82.855585
3.094513 8.255000 82.885707
3.055440 8.258000 82.915829
3.016487 8.261000 82.945951
2.977659 8.264000 82.976073
2.938961 8.267000 83.006195
2.900396 8.270000 83.036317
2.861969 8.273000 83.066439
2.823685 8.276000 83.096561
2.785548 8.279000 83.126683
2.747563 8.282000 83.156805
2.709734 8.285000 83.186927
2.672067 8.288000 83.217049
2.634565 8.291000 83.247171
2.597234 8.294000 83.277293
2.560077 8.297000 83.307415
2.523101 8.300000 83.337537
2.486309 8.303000 83.367659
2.449706 8.306000 83.397781
2.413298 8.309000 83.427903
2.377088 8.312000 83.458025
2.341081 8.315000 83.488147
2.305283 8.318000 83.518269
2.269696 8.321000 83.548391
2.234328 8.324000 83.578513
2.199180 8.327000 83.608635
2.164259 8.330000 83.638757
2.129569 8.333000 83.668879
2.095113 8.336000 83.699001
2.060897 8.339000 83.729123
2.026923 8.342000 83.759245
1.993198 8.345000 83.789367
1.959724 8.348000 83.819489
1.926505 8.351000 83.849611
1.893546 8.354000 83.879733
1.860849 8.357000 83.909855
1.828420 8.360000 83.939977
1.796260 8.363000 83.970099
1.764374 8.366000 84.000221
1.732764 8.369000 84.030343
1.701435 8.372000 84.060465
1.670388 8.375000 84.090587
1.639627 8.378000 84.120709
1.609154 8.381000 84.150831
1.578972 8.384000 84.180953
1.549083 8.387000 84.211075
1.519490 8.390000 84.241197
1.490194 8.393000 84.271319
1.461198 8.396000 84.301441
1.432503 8.399000 84.331563
1.404111 8.402000 84.361685
1.376023 8.405000 84.391807
1.348241 8.408000 84.421929
1.320765 8.411000 84.452051
1.293597 8.414000 84.482173
1.266738 8.417000 84.512295
1.240188 8.420000 84.542417
1.213947 8.423000 84.572539
1.188016 8.426000 84.602661
1.162395 8.429000 84.632783
1.137085 8.432000 84.662905
1.112084 8.435000 84.693027
1.087393 8.438000 84.723149
1.063011 8.441000 84.753271
1.038938 8.444000 84.783393
1.015173 8.447000 84.813515
0.991715 8.450000 84.843637
0.968564 8.453000 84.873759
0.945717 8.456000 84.903881
0.923174 8.459000 84.934003
0.900934 8.462000 84.964125
0.878995 8.465000 84.994247
0.857355 8.468000 85.024369
0.836013 8.471000 85.054491
0.814967 8.474000 85.084613
0.794216 8.477000 85.114735
0.773757 8.480000 85.144857
0.753588 8.483000 85.174979
0.733707 8.486000 85.205101
0.714112 8.489000 85.235223
0.694801 8.492000 85.265345
0.675771 8.495000 85.295467
0.657020 8.498000 85.325589
0.638546 8.501000 85.355711
0.620346 8.504000 85.385833
0.602417 8.507000 85.415955
0.584757 8.510000 85.446077
0.567363 8.513000 85.476199
0.550233 8.516000 85.506321
0.533364 8.519000 85.536443
0.516753 8.522000 85.566565
0.500397 8.525000 85.596687
0.484294 8.528000 85.626809
0.468441 8.531000 85.656931
0.452835 8.534000 85.687053
0.437472 8.537000 85.717175
0.422352 8.540000 85.747297
0.407469 8.543000 85.777419
0.392820 8.546000 85.807541
0.378401 8.549000 85.837663
0.364222 8.552000 85.867785
0.350285 8.555000 85.897907
0.336589 8.558000 85.928029
0.323133 8.561000 85.958151
0.309915 8.564000 85.988273
0.296936 8.567000 86.018395
0.284195 8.570000 86.048517
0.271690 8.573000 86.078639
0.259422 8.576000 86.108761
0.247388 8.579000 86.138883
0.235589 8.582000 86.169005
0.224022 8.585000 86.199127
0.212685 8.588000 86.229249
0.201574 8.591000 86.259371
0.190684 8.594000 86.289493
0.180021 8.597000 86.319615
0.169583 8.600000 86.349737
0.159369 8.603000 86.379859
0.149378 8.606000 86.409981
0.139608 8.609000 86.440103
0.130058 8.612000 86.470225
0.120725 8.615000 86.500347
0.111607 8.618000 86.530469
0.102702 8.621000 86.560591
0.094005 8.624000 86.590713
0.085514 8.627000 86.620835
0.077222 8.630000 86.650957
0.069124 8.633000 86.681079
0.061213 8.636000 86.711201
0.053478 8.639000 86.741323
0.045906 8.642000 86.771445
0.038479 8.645000 86.801567
0.031171 8.648000 86.831689
0.023944 8.651000 86.861811
0.016737 8.654000 86.891933
0.009449 8.657000 86.922055
0.001949 8.660000 86.952177
0.000000 8.661000 86.962218

View File

@ -0,0 +1,538 @@
# Energy(MeV) mg/cm2 cm
# Starting Energy: 70 MeV
70.000000 0.000000 0.000000
69.876080 0.022000 0.205127
69.752015 0.044000 0.410255
69.627805 0.066000 0.615382
69.503449 0.088000 0.820510
69.378946 0.110000 1.025637
69.254297 0.132000 1.230764
69.129499 0.154000 1.435892
69.004554 0.176000 1.641019
68.879460 0.198000 1.846147
68.754217 0.220000 2.051274
68.628825 0.242000 2.256402
68.503282 0.264000 2.461529
68.377589 0.286000 2.666656
68.251744 0.308000 2.871784
68.125747 0.330000 3.076911
67.999598 0.352000 3.282039
67.873296 0.374000 3.487166
67.746841 0.396000 3.692293
67.620231 0.418000 3.897421
67.493467 0.440000 4.102548
67.366548 0.462000 4.307676
67.239472 0.484000 4.512803
67.112241 0.506000 4.717930
66.984852 0.528000 4.923058
66.857306 0.550000 5.128185
66.729602 0.572000 5.333313
66.601739 0.594000 5.538440
66.473717 0.616000 5.743568
66.345535 0.638000 5.948695
66.217192 0.660000 6.153822
66.088689 0.682000 6.358950
65.960023 0.704000 6.564077
65.831195 0.726000 6.769205
65.702204 0.748000 6.974332
65.573050 0.770000 7.179459
65.443731 0.792000 7.384587
65.314248 0.814000 7.589714
65.184599 0.836000 7.794842
65.054784 0.858000 7.999969
64.924802 0.880000 8.205097
64.794652 0.902000 8.410224
64.664335 0.924000 8.615351
64.533849 0.946000 8.820479
64.403193 0.968000 9.025606
64.272368 0.990000 9.230734
64.141371 1.012000 9.435861
64.010204 1.034000 9.640988
63.878864 1.056000 9.846116
63.747351 1.078000 10.051243
63.615665 1.100000 10.256371
63.483805 1.122000 10.461498
63.351770 1.144000 10.666625
63.219560 1.166000 10.871753
63.087173 1.188000 11.076880
62.954609 1.210000 11.282008
62.821868 1.232000 11.487135
62.688948 1.254000 11.692263
62.555849 1.276000 11.897390
62.422570 1.298000 12.102517
62.289111 1.320000 12.307645
62.155470 1.342000 12.512772
62.021647 1.364000 12.717900
61.887642 1.386000 12.923027
61.753453 1.408000 13.128154
61.619079 1.430000 13.333282
61.484521 1.452000 13.538409
61.349776 1.474000 13.743537
61.214845 1.496000 13.948664
61.079727 1.518000 14.153791
60.944420 1.540000 14.358919
60.808924 1.562000 14.564046
60.673238 1.584000 14.769174
60.537362 1.606000 14.974301
60.401295 1.628000 15.179429
60.265035 1.650000 15.384556
60.128582 1.672000 15.589683
59.991935 1.694000 15.794811
59.855094 1.716000 15.999938
59.718057 1.738000 16.205066
59.580824 1.760000 16.410193
59.443393 1.782000 16.615320
59.305764 1.804000 16.820448
59.167936 1.826000 17.025575
59.029909 1.848000 17.230703
58.891681 1.870000 17.435830
58.753251 1.892000 17.640958
58.614618 1.914000 17.846085
58.475783 1.936000 18.051212
58.336743 1.958000 18.256340
58.197497 1.980000 18.461467
58.058046 2.002000 18.666595
57.918388 2.024000 18.871722
57.778521 2.046000 19.076849
57.638446 2.068000 19.281977
57.498161 2.090000 19.487104
57.357665 2.112000 19.692232
57.216958 2.134000 19.897359
57.076038 2.156000 20.102486
56.934904 2.178000 20.307614
56.793555 2.200000 20.512741
56.651991 2.222000 20.717869
56.510210 2.244000 20.922996
56.368211 2.266000 21.128124
56.225994 2.288000 21.333251
56.083557 2.310000 21.538378
55.940900 2.332000 21.743506
55.798020 2.354000 21.948633
55.654918 2.376000 22.153761
55.511592 2.398000 22.358888
55.368042 2.420000 22.564015
55.224265 2.442000 22.769143
55.080261 2.464000 22.974270
54.936029 2.486000 23.179398
54.791568 2.508000 23.384525
54.646877 2.530000 23.589652
54.501954 2.552000 23.794780
54.356799 2.574000 23.999907
54.211410 2.596000 24.205035
54.065787 2.618000 24.410162
53.919927 2.640000 24.615290
53.773830 2.662000 24.820417
53.627495 2.684000 25.025544
53.480921 2.706000 25.230672
53.334106 2.728000 25.435799
53.187049 2.750000 25.640927
53.039750 2.772000 25.846054
52.892206 2.794000 26.051181
52.744416 2.816000 26.256309
52.596380 2.838000 26.461436
52.448096 2.860000 26.666564
52.299563 2.882000 26.871691
52.150779 2.904000 27.076819
52.001744 2.926000 27.281946
51.852455 2.948000 27.487073
51.702913 2.970000 27.692201
51.553114 2.992000 27.897328
51.403059 3.014000 28.102456
51.252745 3.036000 28.307583
51.102172 3.058000 28.512710
50.951338 3.080000 28.717838
50.800242 3.102000 28.922965
50.648882 3.124000 29.128093
50.497256 3.146000 29.333220
50.345365 3.168000 29.538347
50.193205 3.190000 29.743475
50.040776 3.212000 29.948602
49.888076 3.234000 30.153730
49.735104 3.256000 30.358857
49.581858 3.278000 30.563985
49.428337 3.300000 30.769112
49.274540 3.322000 30.974239
49.120464 3.344000 31.179367
48.966108 3.366000 31.384494
48.811471 3.388000 31.589622
48.656552 3.410000 31.794749
48.501348 3.432000 31.999876
48.345858 3.454000 32.205004
48.190080 3.476000 32.410131
48.034014 3.498000 32.615259
47.877656 3.520000 32.820386
47.721006 3.542000 33.025513
47.564063 3.564000 33.230641
47.406823 3.586000 33.435768
47.249286 3.608000 33.640896
47.091450 3.630000 33.846023
46.933313 3.652000 34.051151
46.774873 3.674000 34.256278
46.616129 3.696000 34.461405
46.457079 3.718000 34.666533
46.297721 3.740000 34.871660
46.138054 3.762000 35.076788
45.978075 3.784000 35.281915
45.817782 3.806000 35.487042
45.657174 3.828000 35.692170
45.496250 3.850000 35.897297
45.335006 3.872000 36.102425
45.173441 3.894000 36.307552
45.011554 3.916000 36.512679
44.849342 3.938000 36.717807
44.686803 3.960000 36.922934
44.523935 3.982000 37.128062
44.360737 4.004000 37.333189
44.197205 4.026000 37.538317
44.033339 4.048000 37.743444
43.869136 4.070000 37.948571
43.704594 4.092000 38.153699
43.539711 4.114000 38.358826
43.374484 4.136000 38.563954
43.208912 4.158000 38.769081
43.042992 4.180000 38.974208
42.876723 4.202000 39.179336
42.710101 4.224000 39.384463
42.543125 4.246000 39.589591
42.375792 4.268000 39.794718
42.208101 4.290000 39.999846
42.040047 4.312000 40.204973
41.871631 4.334000 40.410100
41.702848 4.356000 40.615228
41.533697 4.378000 40.820355
41.364175 4.400000 41.025483
41.194279 4.422000 41.230610
41.024007 4.444000 41.435737
40.853357 4.466000 41.640865
40.682327 4.488000 41.845992
40.510912 4.510000 42.051120
40.339111 4.532000 42.256247
40.166922 4.554000 42.461374
39.994341 4.576000 42.666502
39.821365 4.598000 42.871629
39.647993 4.620000 43.076757
39.474221 4.642000 43.281884
39.300047 4.664000 43.487012
39.125467 4.686000 43.692139
38.950478 4.708000 43.897266
38.775079 4.730000 44.102394
38.599265 4.752000 44.307521
38.423034 4.774000 44.512649
38.246383 4.796000 44.717776
38.069309 4.818000 44.922903
37.891809 4.840000 45.128031
37.713879 4.862000 45.333158
37.535516 4.884000 45.538286
37.356718 4.906000 45.743413
37.177481 4.928000 45.948540
36.997801 4.950000 46.153668
36.817675 4.972000 46.358795
36.637100 4.994000 46.563923
36.456073 5.016000 46.769050
36.274589 5.038000 46.974178
36.092646 5.060000 47.179305
35.910240 5.082000 47.384432
35.727367 5.104000 47.589560
35.544023 5.126000 47.794687
35.360206 5.148000 47.999815
35.175910 5.170000 48.204942
34.991132 5.192000 48.410069
34.805869 5.214000 48.615197
34.620116 5.236000 48.820324
34.433870 5.258000 49.025452
34.247126 5.280000 49.230579
34.059880 5.302000 49.435707
33.872128 5.324000 49.640834
33.683865 5.346000 49.845961
33.495089 5.368000 50.051089
33.305793 5.390000 50.256216
33.115974 5.412000 50.461344
32.925627 5.434000 50.666471
32.734748 5.456000 50.871598
32.543332 5.478000 51.076726
32.351374 5.500000 51.281853
32.158869 5.522000 51.486981
31.965813 5.544000 51.692108
31.772201 5.566000 51.897235
31.578027 5.588000 52.102363
31.383287 5.610000 52.307490
31.187975 5.632000 52.512618
30.992086 5.654000 52.717745
30.795615 5.676000 52.922873
30.598556 5.698000 53.128000
30.400904 5.720000 53.333127
30.202652 5.742000 53.538255
30.003796 5.764000 53.743382
29.804329 5.786000 53.948510
29.604246 5.808000 54.153637
29.403540 5.830000 54.358764
29.202205 5.852000 54.563892
29.000235 5.874000 54.769019
28.797623 5.896000 54.974147
28.594363 5.918000 55.179274
28.390448 5.940000 55.384401
28.185872 5.962000 55.589529
27.980627 5.984000 55.794656
27.774706 6.006000 55.999784
27.568102 6.028000 56.204911
27.360808 6.050000 56.410039
27.152817 6.072000 56.615166
26.944120 6.094000 56.820293
26.734709 6.116000 57.025421
26.524577 6.138000 57.230548
26.313715 6.160000 57.435676
26.102116 6.182000 57.640803
25.889770 6.204000 57.845930
25.676668 6.226000 58.051058
25.462802 6.248000 58.256185
25.248162 6.270000 58.461313
25.032740 6.292000 58.666440
24.816524 6.314000 58.871567
24.599506 6.336000 59.076695
24.381675 6.358000 59.281822
24.163021 6.380000 59.486950
23.943533 6.402000 59.692077
23.723200 6.424000 59.897205
23.502011 6.446000 60.102332
23.279953 6.468000 60.307459
23.057016 6.490000 60.512587
22.833187 6.512000 60.717714
22.608453 6.534000 60.922842
22.382801 6.556000 61.127969
22.156217 6.578000 61.333096
21.928688 6.600000 61.538224
21.700200 6.622000 61.743351
21.470737 6.644000 61.948479
21.240285 6.666000 62.153606
21.008827 6.688000 62.358734
20.776347 6.710000 62.563861
20.542829 6.732000 62.768988
20.308254 6.754000 62.974116
20.072609 6.776000 63.179243
19.835957 6.798000 63.384371
19.598318 6.820000 63.589498
19.359680 6.842000 63.794625
19.120032 6.864000 63.999753
18.879360 6.886000 64.204880
18.637652 6.908000 64.410008
18.394895 6.930000 64.615135
18.151076 6.952000 64.820262
17.906180 6.974000 65.025390
17.660193 6.996000 65.230517
17.413102 7.018000 65.435645
17.164892 7.040000 65.640772
16.915547 7.062000 65.845900
16.665053 7.084000 66.051027
16.413394 7.106000 66.256154
16.160552 7.128000 66.461282
15.906513 7.150000 66.666409
15.651259 7.172000 66.871537
15.394773 7.194000 67.076664
15.137037 7.216000 67.281791
14.878032 7.238000 67.486919
14.617741 7.260000 67.692046
14.356144 7.282000 67.897174
14.093221 7.304000 68.102301
13.828952 7.326000 68.307428
13.563318 7.348000 68.512556
13.296297 7.370000 68.717683
13.027867 7.392000 68.922811
12.758007 7.414000 69.127938
12.486695 7.436000 69.333066
12.213909 7.458000 69.538193
11.939625 7.480000 69.743320
11.663822 7.502000 69.948448
11.386476 7.524000 70.153575
11.107570 7.546000 70.358703
10.827242 7.568000 70.563830
10.545561 7.590000 70.768957
10.262533 7.612000 70.974085
9.978162 7.634000 71.179212
9.692461 7.656000 71.384340
9.405447 7.678000 71.589467
9.117143 7.700000 71.794595
8.827581 7.722000 71.999722
8.536807 7.744000 72.204849
8.244875 7.766000 72.409977
7.951860 7.788000 72.615104
7.657853 7.810000 72.820232
7.362971 7.832000 73.025359
7.309274 7.836000 73.062655
7.255553 7.840000 73.099951
7.201810 7.844000 73.137247
7.148046 7.848000 73.174543
7.094262 7.852000 73.211838
7.040458 7.856000 73.249134
6.986609 7.860000 73.286430
6.932705 7.864000 73.323726
6.878746 7.868000 73.361022
6.824729 7.872000 73.398318
6.770654 7.876000 73.435614
6.716523 7.880000 73.472910
6.662336 7.884000 73.510206
6.608092 7.888000 73.547501
6.553792 7.892000 73.584797
6.499438 7.896000 73.622093
6.445029 7.900000 73.659389
6.390567 7.904000 73.696685
6.336051 7.908000 73.733981
6.281483 7.912000 73.771277
6.226863 7.916000 73.808573
6.172193 7.920000 73.845869
6.117472 7.924000 73.883165
6.062703 7.928000 73.920460
6.007885 7.932000 73.957756
5.953021 7.936000 73.995052
5.898111 7.940000 74.032348
5.843156 7.944000 74.069644
5.788158 7.948000 74.106940
5.733119 7.952000 74.144236
5.678038 7.956000 74.181532
5.622919 7.960000 74.218828
5.567762 7.964000 74.256123
5.512570 7.968000 74.293419
5.457343 7.972000 74.330715
5.402085 7.976000 74.368011
5.346797 7.980000 74.405307
5.291480 7.984000 74.442603
5.236138 7.988000 74.479899
5.180773 7.992000 74.517195
5.125387 7.996000 74.554491
5.069982 8.000000 74.591787
5.014562 8.004000 74.629082
4.959129 8.008000 74.666378
4.903687 8.012000 74.703674
4.848238 8.016000 74.740970
4.792785 8.020000 74.778266
4.737333 8.024000 74.815562
4.681884 8.028000 74.852858
4.626442 8.032000 74.890154
4.571013 8.036000 74.927450
4.515598 8.040000 74.964745
4.460204 8.044000 75.002041
4.404834 8.048000 75.039337
4.349493 8.052000 75.076633
4.294186 8.056000 75.113929
4.238918 8.060000 75.151225
4.183695 8.064000 75.188521
4.128522 8.068000 75.225817
4.073404 8.072000 75.263113
4.018348 8.076000 75.300408
3.963360 8.080000 75.337704
3.908446 8.084000 75.375000
3.853614 8.088000 75.412296
3.798869 8.092000 75.449592
3.744220 8.096000 75.486888
3.689673 8.100000 75.524184
3.635236 8.104000 75.561480
3.580918 8.108000 75.598776
3.526726 8.112000 75.636072
3.472668 8.116000 75.673367
3.418754 8.120000 75.710663
3.364992 8.124000 75.747959
3.311391 8.128000 75.785255
3.257962 8.132000 75.822551
3.204712 8.136000 75.859847
3.151652 8.140000 75.897143
3.098793 8.144000 75.934439
3.046144 8.148000 75.971735
2.993715 8.152000 76.009030
2.941518 8.156000 76.046326
2.889563 8.160000 76.083622
2.837861 8.164000 76.120918
2.786423 8.168000 76.158214
2.735261 8.172000 76.195510
2.684385 8.176000 76.232806
2.633807 8.180000 76.270102
2.583538 8.184000 76.307398
2.533591 8.188000 76.344693
2.483975 8.192000 76.381989
2.434704 8.196000 76.419285
2.385788 8.200000 76.456581
2.337239 8.204000 76.493877
2.289068 8.208000 76.531173
2.241287 8.212000 76.568469
2.193906 8.216000 76.605765
2.146936 8.220000 76.643061
2.100388 8.224000 76.680357
2.054274 8.228000 76.717652
2.008602 8.232000 76.754948
1.963383 8.236000 76.792244
1.918627 8.240000 76.829540
1.874342 8.244000 76.866836
1.830539 8.248000 76.904132
1.787225 8.252000 76.941428
1.744409 8.256000 76.978724
1.702099 8.260000 77.016020
1.660301 8.264000 77.053315
1.619024 8.268000 77.090611
1.578272 8.272000 77.127907
1.538053 8.276000 77.165203
1.498372 8.280000 77.202499
1.459233 8.284000 77.239795
1.420641 8.288000 77.277091
1.382600 8.292000 77.314387
1.345114 8.296000 77.351683
1.308184 8.300000 77.388978
1.271813 8.304000 77.426274
1.236003 8.308000 77.463570
1.200756 8.312000 77.500866
1.166071 8.316000 77.538162
1.131950 8.320000 77.575458
1.098392 8.324000 77.612754
1.065395 8.328000 77.650050
1.032959 8.332000 77.687346
1.001083 8.336000 77.724642
0.969763 8.340000 77.761937
0.938998 8.344000 77.799233
0.908785 8.348000 77.836529
0.879119 8.352000 77.873825
0.849998 8.356000 77.911121
0.821417 8.360000 77.948417
0.793372 8.364000 77.985713
0.765858 8.368000 78.023009
0.738870 8.372000 78.060305
0.712403 8.376000 78.097600
0.686452 8.380000 78.134896
0.661011 8.384000 78.172192
0.636073 8.388000 78.209488
0.611633 8.392000 78.246784
0.587685 8.396000 78.284080
0.564222 8.400000 78.321376
0.541238 8.404000 78.358672
0.518725 8.408000 78.395968
0.496678 8.412000 78.433264
0.475089 8.416000 78.470559
0.453952 8.420000 78.507855
0.433259 8.424000 78.545151
0.413005 8.428000 78.582447
0.393179 8.432000 78.619743
0.373775 8.436000 78.657039
0.354813 8.440000 78.694335
0.336291 8.444000 78.731631
0.318207 8.448000 78.768927
0.300558 8.452000 78.806222
0.283343 8.456000 78.843518
0.266560 8.460000 78.880814
0.250206 8.464000 78.918110
0.234278 8.468000 78.955406
0.218772 8.472000 78.992702
0.203682 8.476000 79.029998
0.188993 8.480000 79.067294
0.174713 8.484000 79.104590
0.160840 8.488000 79.141885
0.147372 8.492000 79.179181
0.134303 8.496000 79.216477
0.121631 8.500000 79.253773
0.109349 8.504000 79.291069
0.097451 8.508000 79.328365
0.085927 8.512000 79.365661
0.074766 8.516000 79.402957
0.063954 8.520000 79.440253
0.053468 8.524000 79.477549
0.043278 8.528000 79.514844
0.033336 8.532000 79.552140
0.023566 8.536000 79.589436
0.013823 8.540000 79.626732
0.003838 8.544000 79.664028
0.001296 8.545000 79.673352

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

296
fit_a1c1_cfrac.C Normal file
View File

@ -0,0 +1,296 @@
// fit_a1c1_cfrac.C
// =============================================================================
// Offline per-cell "gain match" for the A1C1 linear centre-fold model.
//
// The raw cfrac = cpMax/(apSum+cpMax) pedestal floats with the arbitrary
// anode/cathode gain, so the model cfrac = cfmin[cell] + k[cell]*fold has to be
// re-fit per dataset. This macro does that fit OFFLINE from an already-processed
// results file (no reprocessing of raw data), replacing the in-line autocal that
// used to live in TrackRecon.C.
//
// It reads the reference histograms
// Benchmark_QQQ_A1C1_cfrac_vs_ref (X = true z = pcz_ref, Y = cfrac)
// Benchmark_SX3_A1C1_cfrac_vs_ref
// filled from A1C2 events (where the true z is known from the crossover), folds
// each cell about its centre (fold = |z - z_centre| / halfcell, in [0,1]) and
// does a weighted least-squares fit of cfrac vs fold per cathode cell. QQQ and
// SX3 are combined (same proportional-counter cells).
//
// Output: a per-cell table, paste-ready C++ array literals for TrackRecon.C
// (a1c1_cfmin_<DATASET>[7] / a1c1_k_<DATASET>[7]), and optionally a .dat file.
//
// Usage (compile once with + then call):
// root -l -b -q 'fit_a1c1_cfrac.C+("Output_17F/Output_17F.root")' // build
// MAIN band: fit_a1c1_cfrac("Output_17F/Output_17F.root","17F",0.25,1.05)
// LOW band: fit_a1c1_cfrac("Output_17F/Output_17F.root","17F",0.00,0.25,50,false,"2")
// 27Al: fit_a1c1_cfrac("Output_27Al/output_27Al.root","27Al",0.10,1.05)
// Args: cfrac_min, cfrac_max (band window), min_counts (per-cell fit threshold),
// write_dat (dump a1c1_cfrac_<DATASET>.dat), band ("" main, "2" low band ->
// prints a1c1_cfmin2_<DATASET>), all_cells (pool all 7 cells into one fit
// and broadcast -- robust when per-cell stats are thin / pedestals uniform).
// ALL-CELLS: fit_a1c1_cfrac("Output_cal/17F.root","17F",0.25,1.05,50,false,"",true)
// =============================================================================
#include <TFile.h>
#include <TH1.h>
#include <TH2.h>
#include <TKey.h>
#include <TDirectory.h>
#include <TMath.h>
#include <TString.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
namespace {
// cathode wire grid; cell i spans zg[i] (high) .. zg[i+1] (low)
const double zg[8] = {147.998, 101.946, 59.7634, 19.6965,
-19.6965, -59.7634, -101.946, -147.998};
int cellOf(double z) {
for (int i = 0; i < 7; ++i)
if (z <= zg[i] && z > zg[i + 1]) return i;
return -1;
}
// recursively search a directory tree for a TH2 by name (folders vary by group)
TH2 *findTH2(TDirectory *dir, const std::string &name) {
if (TH2 *h = dynamic_cast<TH2 *>(dir->Get(name.c_str()))) return h;
TIter next(dir->GetListOfKeys());
TKey *key;
while ((key = (TKey *)next())) {
TObject *obj = key->ReadObj();
if (TDirectory *sub = dynamic_cast<TDirectory *>(obj)) {
if (TH2 *h = findTH2(sub, name)) return h;
}
}
return nullptr;
}
} // namespace
// cfrac_min/cfrac_max bracket the band to fit: [0.25, 1.05] for the MAIN band,
// [0.0, 0.25] for the 17F low (incomplete-integration) band. band="" prints the
// a1c1_cfmin_<dataset> arrays; band="2" prints a1c1_cfmin2_<dataset> (the low band).
void fit_a1c1_cfrac(const char *filename, const char *dataset = "DATA",
double cfrac_min = 0.0, double cfrac_max = 1.05,
long min_counts = 50, bool write_dat = false,
const char *band = "", bool all_cells = false) {
TFile *f = TFile::Open(filename, "READ");
if (!f || f->IsZombie()) {
std::cerr << "fit_a1c1_cfrac: cannot open " << filename << std::endl;
return;
}
const char *names[2] = {"Benchmark_QQQ_A1C1_cfrac_vs_ref",
"Benchmark_SX3_A1C1_cfrac_vs_ref"};
// weighted OLS accumulators per cell: cfrac = cfmin + k*fold
double n[7] = {0}, sf[7] = {0}, sff[7] = {0}, sc[7] = {0}, sfc[7] = {0};
for (int s = 0; s < 2; ++s) {
TH2 *h = findTH2(f, names[s]);
if (!h) {
std::cout << " (note: " << names[s] << " not found -- skipping)" << std::endl;
continue;
}
std::cout << "Using " << names[s] << " (" << h->GetEntries() << " entries)" << std::endl;
const int nx = h->GetNbinsX(), ny = h->GetNbinsY();
for (int ix = 1; ix <= nx; ++ix) {
const double z = h->GetXaxis()->GetBinCenter(ix);
const int c = cellOf(z);
if (c < 0) continue;
const double zc = 0.5 * (zg[c] + zg[c + 1]);
const double half = 0.5 * (zg[c] - zg[c + 1]);
if (half <= 0.0) continue;
const double fold = TMath::Abs(z - zc) / half; // [0,1]
for (int iy = 1; iy <= ny; ++iy) {
const double w = h->GetBinContent(ix, iy);
if (w <= 0.0) continue;
const double cfrac = h->GetYaxis()->GetBinCenter(iy);
if (cfrac < cfrac_min || cfrac > cfrac_max) continue;
n[c] += w;
sf[c] += w * fold;
sff[c] += w * fold * fold;
sc[c] += w * cfrac;
sfc[c] += w * fold * cfrac;
}
}
}
// per-cell weighted least-squares; keep a fallback for starved cells
const double cfmin_fallback = 0.40, k_fallback = 0.075;
double cfmin[7], k[7];
if (all_cells) {
// pool every cell into one fit. fold is already cell-relative (|z-zc|/half),
// so pooling the (fold, cfrac) pairs is valid -- robust when per-cell stats
// are thin and the pedestals are ~uniform. Same value written to all 7 cells.
double N = 0, SF = 0, SFF = 0, SC = 0, SFC = 0;
for (int c = 0; c < 7; ++c) { N += n[c]; SF += sf[c]; SFF += sff[c]; SC += sc[c]; SFC += sfc[c]; }
double cf = cfmin_fallback, kk = k_fallback;
const char *status = "FALLBACK (starved)";
if (N > min_counts) {
const double denom = N * SFF - SF * SF;
if (TMath::Abs(denom) > 1e-9) {
const double kfit = (N * SFC - SF * SC) / denom;
const double cffit = (SC - kfit * SF) / N;
if (kfit > 0.01) { cf = cffit; kk = kfit; status = "fit"; }
else status = "FALLBACK (flat k)";
}
}
for (int c = 0; c < 7; ++c) { cfmin[c] = cf; k[c] = kk; }
printf("\n ALL-CELLS pooled fit: cfmin=%.6f k=%.6f n(eff)=%.0f %s\n", cf, kk, N, status);
} else {
std::cout << "\n cell cfmin k n(eff) status" << std::endl;
std::cout << " ---- --------- --------- -------- ------" << std::endl;
for (int c = 0; c < 7; ++c) {
double cf = cfmin_fallback, kk = k_fallback;
const char *status = "FALLBACK (starved)";
if (n[c] > min_counts) {
const double denom = n[c] * sff[c] - sf[c] * sf[c];
if (TMath::Abs(denom) > 1e-9) {
const double kfit = (n[c] * sfc[c] - sf[c] * sc[c]) / denom;
const double cffit = (sc[c] - kfit * sf[c]) / n[c];
if (kfit > 0.01) { // reject degenerate/flat fit
cf = cffit;
kk = kfit;
status = "fit";
} else {
status = "FALLBACK (flat k)";
}
}
}
cfmin[c] = cf;
k[c] = kk;
printf(" %d %9.6f %9.6f %8.0f %s\n", c, cf, kk, n[c], status);
}
}
// paste-ready literals for TrackRecon.C (band="" -> main set, "2" -> low band)
printf("\n// ---- paste into TrackRecon.C (cfrac in [%.2f, %.2f]) ----\n", cfrac_min, cfrac_max);
printf("static const double a1c1_cfmin%s_%s[7] = {", band, dataset);
for (int c = 0; c < 7; ++c) printf("%.6f%s", cfmin[c], c < 6 ? ", " : "};\n");
printf("static const double a1c1_k%s_%s[7] = {", band, dataset);
for (int c = 0; c < 7; ++c) printf("%.6f%s", k[c], c < 6 ? ", " : "};\n");
if (write_dat) {
const std::string fn = std::string("a1c1_cfrac_") + dataset + ".dat";
std::ofstream out(fn);
out << "# cell cfmin k (offline fit cfrac = cfmin + k*fold; dataset=" << dataset << ")\n";
for (int c = 0; c < 7; ++c) out << c << " " << cfmin[c] << " " << k[c] << "\n";
out.close();
std::cout << "\nwrote " << fn << std::endl;
}
f->Close();
}
// =============================================================================
// REFERENCE-FREE gain match.
//
// Does NOT use the A1C2 true-z reference. Reads the per-cell A1C1 cfrac
// histogram Benchmark_{QQQ,SX3}_trueA1C1_cfrac_vs_cell (cell assignment is pure
// geometry) and recovers the constants from the EDGES of each cell's cfrac
// distribution: within a cell cfrac = cfmin + k*fold with fold in [0,1], so the
// low percentile ~ cfmin (fold->0, cell centre) and the high percentile ~
// cfmin+k (fold->1, at the wire). Robust percentiles (plo/phi) are used instead
// of min/max.
//
// This aligns the per-cell pedestals (the actual gain match) WITHOUT a reference,
// but it cannot fix the absolute z scale -- it assumes the linear model and that
// each cell is illuminated across its length. If shared_k=true, a single
// geometric k (median of the per-cell spans) is used for every cell and only the
// per-cell cfmin pedestal is taken from the data -- the most robust mode.
//
// Usage:
// root -l -b -q 'fit_a1c1_cfrac.C+("Output_17F/Output_17F.root")' // compile
// root -l -b -q 'fit_a1c1_cfrac_reffree("Output_17F/Output_17F.root","17F")'
// =============================================================================
void fit_a1c1_cfrac_reffree(const char *filename, const char *dataset = "DATA",
double plo = 0.05, double phi = 0.95,
bool shared_k = false, double min_counts = 50,
bool write_dat = false) {
TFile *f = TFile::Open(filename, "READ");
if (!f || f->IsZombie()) {
std::cerr << "fit_a1c1_cfrac_reffree: cannot open " << filename << std::endl;
return;
}
const char *names[2] = {"Benchmark_QQQ_trueA1C1_cfrac_vs_cell",
"Benchmark_SX3_trueA1C1_cfrac_vs_cell"};
// sum the QQQ + SX3 per-cell cfrac histograms into one (cell x cfrac)
TH2 *acc = nullptr;
for (int s = 0; s < 2; ++s) {
TH2 *h = findTH2(f, names[s]);
if (!h) {
std::cout << " (note: " << names[s] << " not found -- skipping)" << std::endl;
continue;
}
std::cout << "Using " << names[s] << " (" << h->GetEntries() << " entries)" << std::endl;
if (!acc) { acc = (TH2 *)h->Clone("acc_cfrac_vs_cell"); acc->SetDirectory(nullptr); }
else acc->Add(h);
}
if (!acc) { std::cerr << "no cfrac_vs_cell histograms found" << std::endl; f->Close(); return; }
const double cfmin_fallback = 0.40, k_fallback = 0.075;
double cfmin[7], k[7], span[7];
bool ok[7];
std::cout << "\n cell cfmin cfmin+k k n status" << std::endl;
std::cout << " ---- --------- --------- --------- ------ ------" << std::endl;
for (int c = 0; c < 7; ++c) {
TH1D *proj = acc->ProjectionY(Form("proj_c%d", c), c + 1, c + 1);
const double n = proj->Integral();
double lo = cfmin_fallback, hi = cfmin_fallback + k_fallback;
ok[c] = false;
if (n > min_counts) {
double q[2], p[2] = {plo, phi};
proj->GetQuantiles(2, q, p);
lo = q[0];
hi = q[1];
ok[c] = (hi - lo > 0.01);
}
cfmin[c] = ok[c] ? lo : cfmin_fallback;
span[c] = ok[c] ? (hi - lo) : k_fallback;
k[c] = span[c];
printf(" %d %9.6f %9.6f %9.6f %6.0f %s\n", c, cfmin[c],
cfmin[c] + span[c], span[c], n, ok[c] ? "fit" : "FALLBACK");
delete proj;
}
if (shared_k) {
// median of the well-determined per-cell spans -> one geometric k for all cells
double v[7];
int m = 0;
for (int c = 0; c < 7; ++c) if (ok[c]) v[m++] = span[c];
double kg = k_fallback;
if (m > 0) {
std::sort(v, v + m);
kg = (m % 2) ? v[m / 2] : 0.5 * (v[m / 2 - 1] + v[m / 2]);
}
for (int c = 0; c < 7; ++c) k[c] = kg;
std::cout << "\nshared geometric k = " << kg << " (median of " << m << " fitted cells)" << std::endl;
}
printf("\n// ---- paste into TrackRecon.C (reference-free gain match) ----\n");
printf("static const double a1c1_cfmin_%s[7] = {", dataset);
for (int c = 0; c < 7; ++c) printf("%.6f%s", cfmin[c], c < 6 ? ", " : "};\n");
printf("static const double a1c1_k_%s[7] = {", dataset);
for (int c = 0; c < 7; ++c) printf("%.6f%s", k[c], c < 6 ? ", " : "};\n");
if (write_dat) {
const std::string fn = std::string("a1c1_cfrac_") + dataset + ".dat";
std::ofstream out(fn);
out << "# cell cfmin k (reference-free gain match, percentiles " << plo << "/" << phi
<< "; dataset=" << dataset << ")\n";
for (int c = 0; c < 7; ++c) out << c << " " << cfmin[c] << " " << k[c] << "\n";
out.close();
std::cout << "\nwrote " << fn << std::endl;
}
delete acc;
f->Close();
}

41
gmsx3/func1.h Executable file
View File

@ -0,0 +1,41 @@
#include "TF1.h"
double model2(double *x, double *par) {
/* 'Potential Well' of width 2a from from xx-a to xx+a
xx is coordinate about the point of origin, set at x=center
v0 is the y-offset of the potential
k is the 'steepness' of the potential
continuous across xx-a and xx+a, and differentiable
*/
double center= par[3];
double xx = x[0]-center;
double a = TMath::Abs(par[0]);
double k = TMath::Abs(par[1]);
double v0 = par[2];
if(xx < -a)
return k*(xx+a)*(xx+a) + v0;
else if(xx > a)
return k*(xx-a)*(xx-a) + v0;
else
return v0;
}
void func1() {
//TF1 f1("bowl",model,-2.,2.,2);
TCanvas c("c1","c1",800,600);
TF1 f1("bowl",model2,-10.,10.,4);
f1.SetMaximum(10);
for(int i=-4; i<4; i++) {
f1.SetParameters(.4,100,2,i); //a, k, v0, center
f1.SetNpx(100000);
if(i==-4) f1.Draw("L");
f1.DrawCopy("L SAME");
c.Modified(); c.Update();
//c.SaveAs(Form("%d.png",out));
while(c.WaitPrimitive());
}
}

216
gmsx3/intgm_sx3.h Executable file
View File

@ -0,0 +1,216 @@
#include "../Armory/HistPlotter.h"
#include <Minuit2/FCNBase.h>
#include <Math/Minimizer.h>
#include <Math/Factory.h>
#include <Math/Functor.h>
#include <TMath.h>
#include <TPad.h>
#include <cassert>
#include <vector>
#include <array>
#include <iostream>
#include <TF1.h>
#include "func1.h"
static long iters=0;
//class intgm_sx3 : public ROOT::Minuit2::FCNBase {
class intgm_sx3 {
int N;
//L.at(0).at(3).at(n) is front strip = 0, back pad = 3, nth datapoint
std::array<std::array<std::vector<double>,4>,4> L,R,B;
//std::array<std::array<double,5>,4> stripedge; //stripedge.at(i).at(j) is the jth edge of the ith strip. there are five edges for the four strips 'i'=0 to 3, (0,1) (1,2) (2,3) (3,4) for each
//the edges are at -2a, -a, 0, a, 2a respectively so we enforce four ratios in the chi2 value - 'a' can be held constant, no need to fit it.
//assume z = M*(aL-bR)
//stripedge[i][1] = max(z) when pad==0 = min(z) when pad==1 this should be -1
//stripedge[i][2] = max(z) when pad==1 = min(z) when pad==2. this should be 0
//stripedge[i][3] = max(z) when pad==2 = min(z) when pad==3. this should be 1
//i.e. stripedge[i][j] = max(z) when pad == j-1, min(z) when pad==j, for i= 1,2,3
//ncounts.at(frontch).at(backch) is the number of (L,R,B) tuples we've filled (frontch,backch) coordinates in the detector
std::array<std::array<long,4>,4> ncounts;
TH1F *localhists[4][4]; //one histogram for each fc, bc combination
HistPlotter *plotter;
TF1 *pos_weight[4];
TF1 *energywell;
public:
intgm_sx3() {
for(int bc=0; bc<4; bc++) {
for(int fc=0; fc<4; fc++) {
L[fc][bc].reserve(1000);
R[fc][bc].reserve(1000);
B[fc][bc].reserve(1000);
//localhists[fc][bc] = new TH1F(Form("h_%d_%d",fc,bc),Form("h_%d_%d",fc,bc),1000,-4.,4.);
ncounts[fc][bc] = 0;
}
pos_weight[bc] = new TF1(Form("b_strip%d",bc),model2,-10,10,4); //from -10, to 10, 4 parameters
pos_weight[bc]->SetParameters(1.0,10,1.,3-2*bc); //centers at 1, 3.,5,7 Width 2a with a=1.0
pos_weight[bc]->SetNpx(1'000'000);
}
energywell = new TF1("ewell",model2,0,2000,4); //0 to 2000 channels, 4 params
energywell->SetParameters(1000,20,1,1500); //center the back E values at 1500 +/- 500
energywell->SetNpx(1'000'000);
N=0;
}
void set_plotter(HistPlotter *p) {plotter=p;}
void set_iters(long i) { iters=i;}
intgm_sx3(HistPlotter *p) : plotter(p) {
for(int bc=0; bc<4; bc++) {
for(int fc=0; fc<4; fc++) {
L[fc][bc].reserve(1000);
R[fc][bc].reserve(1000);
B[fc][bc].reserve(1000);
//localhists[fc][bc] = new TH1F(Form("h_%d_%d",fc,bc),Form("h_%d_%d",fc,bc),1000,-4.,4.);
ncounts[fc][bc] = 0;
}
pos_weight[bc] = new TF1(Form("b_strip%d",bc),model2,-10,10,4); //from -10, to 10, 4 parameters
//a/2, k, v0, center
pos_weight[bc]->SetParameters(0.92,10,1.,-1.*(3-2*bc)); //centers at 7, 5.,3,1 Width 2a with a=1.0
pos_weight[bc]->SetNpx(1'000'000);
}
energywell = new TF1("ewell",model2,0,8000,4); //0 to 2000 channels, 4 params
// energywell->SetParameters(60,10,0,1430); //center the back E values at 1430 +/- 60
energywell->SetParameters(400,10,0,5246); //center the back E values at 5486 +/- 600
energywell->SetNpx(1'000'000);
N=0;
}
inline void fill(int fc, int bc, double leftE, double rightE, double backE) {
/*
*
*/
assert(fc>=0 && fc<=3 && "Front channels should fit the range 0 to 3 inclusive!");
assert(bc>=0 && bc<=3 && "Back channels should fit the range 0 to 3 inclusive!");
if(leftE>0 && rightE >0 && backE>0) {
L[fc][bc].emplace_back(leftE);
R[fc][bc].emplace_back(rightE);
B[fc][bc].emplace_back(backE);
ncounts[fc][bc]+=1;
N+=1;
}
}
inline void print() {
for(int i=0; i<16; i++) {
std::cout << ncounts[i%4][i/4] << std::endl;
}
}
inline void plot(std::string comment, const double* params) {
std::array<double,4> l,r,b,bo,ro,lo,offset,stretch; //aliases to help with book-keeping
std::array<std::array<double,4>,4> back_gains;// back_gains[fc][bc] are for fc,bc firing in combo
for(int ctr=0; ctr<4; ctr++) {
r[ctr] = params[ctr];
}
for(int ctr=4; ctr<20; ctr++) {
int bch = (ctr-4)%4;
int fch = (ctr-4)/4;
back_gains[bch][fch] = params[ctr];
}
for(int ctr=20; ctr<24; ctr++) {
stretch[ctr-20] = params[ctr];
}
for(int ctr=24; ctr<28; ctr++) {
l[ctr-24] = params[ctr];
}
for(int fc=0; fc<4; fc++) {
for(int bc=0; bc<4; bc++) {
for(int n=0; n<ncounts[fc][bc]; n++) {
if(plotter) {
double left = l[fc]*L[fc][bc].at(n);
double right = r[fc]*R[fc][bc].at(n);
double back = back_gains[bc][fc]*B[fc][bc].at(n);
//double zpos = (left - right)/(left+right);
double zpos = stretch[fc]*(left - right)/(left+right);// + offset[fc]; //back;
plotter->Fill2D(Form("normlf_fc%d_%d_%s",fc,bc,comment.c_str()),800,0,1.,800,0,1.,left/back, right/back,"l_vs_r");
plotter->Fill2D(Form("normlf_all_%s",comment.c_str()),800, 0, 1., 800, 0, 1.,left/back, right/back);
plotter->Fill2D(Form("case_f%d_b%d_%s",fc,bc,comment.c_str()),800,0,8192,800,0,8192,left+right,back,"l_vs_r");
plotter->Fill2D(Form("case_all_%s",comment.c_str()),800,0,8192,800,0,8192,left+right,back);
//plotter->Fill2D(Form("z_vs_backe_f%d_b%d_%s",fc,bc,comment.c_str()),800,-10,10,800,0,8192,zpos,back,"z_vs_be");
plotter->Fill2D(Form("z_vs_backe_all_%s",comment.c_str()),800,-10,10,800,0,8192,zpos,back);
} //end if plotter
}// end for-n
}//end for-bc
}//end for-fc
}//end plot()
// double operator()(const std::vector<double>& params) const override{
double eval(const double* params) const {
iters+=1;
std::array<double,4> l,r,b,bo,ro,lo, offset, stretch; //aliases to help with book-keeping
std::array<std::array<double,4>,4> back_gains;// back_gains[fc][bc] are for fc,bc firing in combo
for(int ctr=0; ctr<16; ctr++) {
int bch = (ctr)%4;
int fch = (ctr)/4;
back_gains[bch][fch] = params[ctr];
}
for(int ctr=16; ctr<20; ctr++) {
r[ctr-16] = params[ctr];
l[ctr-16] = 1.0;
}
for(int ctr=20; ctr<24; ctr++) {
stretch[ctr-20] = params[ctr];
}
double result=0, sumcount=0;
for(int fc=0; fc<4; fc++) {
for(int bc=0; bc<4; bc++) {
//if(bc >= 1 || fc >= 1 ) continue;
if(ncounts[fc][bc] == 0 && iters ==0) {
std::cout << "Missing any data in front:" << fc << " back:" << bc << " combination." << std::endl;
}
for(int n=0; n<ncounts[fc][bc] ; n++) {
//double left = l[fc]*L[fc][bc].at(n) + lo[fc];
//double right = r[fc]*R[fc][bc].at(n) + ro[fc];
//double back = b[bc]*B[fc][bc].at(n) + bo[bc];
//double add = TMath::Power(left + right - back,2);
if(B[fc][bc].at(n)<100) continue;//ignore events too close to noise threshold
double left = l[fc]*L[fc][bc].at(n);
double right = r[fc]*R[fc][bc].at(n);
double back = back_gains[bc][fc]*B[fc][bc].at(n);
double lnorm = left/B[fc][bc].at(n);
double rnorm = right/B[fc][bc].at(n);
//double add = TMath::Power(left/back + right/back - 1.0,2);
double add = TMath::Power(left + right - back,2);
double zpos = stretch[fc]*(left - right)/(left+right); //back;
std::cout << zpos << " " << pos_weight[bc]->Eval(zpos) << " " << bc << std::endl;
double add_position = pos_weight[bc]->Eval(zpos);
double eback_align_penalty = energywell->Eval(back);
/* if(back>1000) zmid[fc][bc] += zpos;
if(back>1000 && zpos < zmin[fc][bc]) zmin[fc][bc] = zpos;
if(back> 1000 && zpos > zmax[fc][bc]) zmax[fc][bc] = zpos;
if(back>1000) {
localhists[fc][bc]->Fill(zpos);
}*/
result += add_position;
//result += add;
result += eback_align_penalty;
sumcount+=1;
//if(bc==0) std::cout << add << " " << add_position << " " << zpos << std::endl;
//To avoid drift towards (0,0,0) trivial solution. This value ~1 close to (1,1,1)
//result+=(1e-3/(TMath::Power(l[fc],2)+TMath::Power(r[fc],2)+TMath::Power(b[bc],2)+1e-9));
//result+=(1e-3/(TMath::Power(l[fc],2)+TMath::Power(r[fc],2)+TMath::Power(b[bc],2)+1e-9));
} //end for-n
} //end for-bc
} //end for-fc
result/=sumcount; //normalize, so the value doesn't scream
if(iters%1'000==0) {
std::cout << "iters : " << iters << " params: " << std::endl ;
for(int i=0 ; i< 10; i++) std::cout << params[i] << " " << std::flush;
std::cout<< std::endl;
for(int i=10 ; i< 20; i++) std::cout << params[i] << " " << std::flush;
std::cout << std::endl << " result: " << result << std::endl;
} //end if
return result;
} //end eval()
//double Up() const override { return 1.0; } // Required by minuit2 FCBase
};

338
gmsx3/utilities_orr.h Executable file
View File

@ -0,0 +1,338 @@
#ifndef UTILS_ORR_H
#define UTILS_ORR_H
#include "datatypes.h"
#include "HistPlotter.h"
#include "Geometry_orr.h" //contains orruba geometry constants
#include <cassert>
#include <stdio.h>
#include <cassert>
#include <cstdint>
#include <fcntl.h>
#include <unistd.h>
#include <vector>
//#include <cstring>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <set>
#include <sys/stat.h>
#include "TMath.h"
#include "counters.h"
static named_counter oc("named orruba counters");
inline float get_filesize(std::string filename) {
struct stat st;
stat(filename.c_str(), &st);
return st.st_size;
}
class orruba_params {
/*
*
*/
public:
int chnum=DEFAULT_NULL; //!< global channel number
std::string type = "-";
int id=DEFAULT_NULL;
int layer=DEFAULT_NULL;
int frontback=DEFAULT_NULL;
int updown=DEFAULT_NULL;
int subid=DEFAULT_NULL;
int leftright=DEFAULT_NULL;
float ped=DEFAULT_NULL;
float offset=DEFAULT_NULL;
float gain=DEFAULT_NULL;
float gain2=DEFAULT_NULL; //for use with sx3's
};
class sx3_geometry_scalefactors {
public:
//If sx3 has L, R being the left and right extremities, we choose add, stretch here such that
// x_mm = (x_raw+add)*stretch; so add=abs(L), stretch=75/(abs(L)+R)
float add[4];
float stretch[4];
};
class qqq5_finegains {
public:
std::array<std::pair<float,float>,32> front;
//front.at(30).first = slope at clkpos 0, ring 30 for E front layer
//front.at(30).second = intercept for the same as above
std::array<std::pair<float,float>,4> back;
};
class sx3_fbgains {
public:
//Order of indices is [pad][strip]
float padoffsets[4][4];
float padgains[4][4];
float stripLoffsets[4][4];
float stripLgains[4][4];
float stripRoffsets[4][4];
float stripRgains[4][4];
};
//Metadata ORRUBA needs to know about itself, to be configured at the start
extern std::array<orruba_params,MAX_ORRUBA_CHANS> o_params;
extern std::array<sx3_fbgains,24> sx3_xtalk_gains; //every sx3 needs to be gainmatched as a frontL-back, frontR-back pair (pad strip pair)
extern std::array<sx3_geometry_scalefactors,24> sx3gs;
extern std::array<qqq5_finegains,4> qqq5_fg_dE, qqq5_fg_E;
class type19Raw {
public:
long int timestamp;
std::vector<unsigned short> ch;
std::vector<unsigned short> val;
type19Raw() : timestamp(0), ch(50,0), val(50,0) {} //Reserve 50 for size of these vectors, initial value of zero
void print() const {
/*
print()
Prints type19Raw's contents to stdout for monitoring
*/
std::cout << "------" << std::endl;
for(unsigned int ii=0; ii<ch.size(); ii++) {
std::cout << ch.at(ii) << " " << val.at(ii) << std::endl;
}
}
};
class sx3 {
public:
//TODO: Convert to std::array
//Holds all information in an event, including ped subtraction+scaling. back[2].at(0) will have the largest energy seen in ch2, if any
std::vector<float> back[4];
std::vector<float> frontL[4];
std::vector<float> frontR[4];
double ts = DEFAULT_NULL;
//Easy lookup of final calibrated event. Only filled for valid cases, assumed for now to be 1L, 1R, 1B
float frontX=DEFAULT_NULL;
float frontXmm=DEFAULT_NULL;
float frontE=DEFAULT_NULL;
float backE=DEFAULT_NULL;
int stripF=DEFAULT_NULL;
int stripB=DEFAULT_NULL;
float frontEL=DEFAULT_NULL;
float frontER=DEFAULT_NULL;
float phi=DEFAULT_NULL; //
std::set<int> valid_front_chans;
std::set<int> valid_back_chans;
std::set<int> unmatched_front_chans; //every front channel is unmatched and invalid at first. when it gets matched, it gets removed and sent to valid
bool foundevent=false;
bool valid=false;//valid will be set to false in all cases where we have ambiguity
int flags=-1;//flags settable to different types of values to indicate different invalid situations
void fillevent(const std::string& position, const int subchannel, const float value); //make 'const' what functions don't need to change, helps with performance
void validate(const sx3_fbgains&, const sx3_geometry_scalefactors&);
};
class qqq5 {
public:
//Holds all information in an event, including ped subtraction+scaling. front[2].at(0) will have the largest energy seen in ch2, if any
//TODO: Convert to std::array
std::vector<float> back[4];
std::vector<float> front[32];
double ts = DEFAULT_NULL;
float selftheta=DEFAULT_NULL,selfrho=DEFAULT_NULL;
//Easy lookup of the final calibrated event. Only filled for valid cases.
double frontE=DEFAULT_NULL;
double backE=DEFAULT_NULL;
int frontch;
int backch;
std::pair<int,int> adj_front_strips = {-1,-1};
std::pair<int,int> adj_back_strips = {-1,-1};
std::set<int> valid_front_chans; //list of channels that fire. can inspect size() of these to see if there are front/back events
std::set<int> valid_back_chans; // we use std::set since it makes for very readable code
bool foundevent=false;
bool valid=false; //valid will be set to false in all cases where we have ambiguity
int flags=-1; //flags settable to different types of values to indicate different invalid situations
void fillevent(const std::string& position, const int subchannel, const float value); //make 'const' what functions don't need to change, helps with performance
void validate();
};
struct orrubaevent {
//Every clean, valid charged-particle event will have these four parts
float dE=DEFAULT_NULL; //!< true energy-loss in the dE layer. Found by gainmatching ADC readout to alpha data
float E=DEFAULT_NULL; //!< energy deposited in the E layer. When summed with dE, gives true energy in keV deposited by the particle in ORRUBA
float dE_PID = DEFAULT_NULL; //!< dE scaled for dE-layer's thickness, reducing the spread due to angular straggling by explicitly accounting for it. This will give a sharper pid plot that can be gated on better
float dE_linPID = DEFAULT_NULL; //!< dE_PID, but linearized using the prescription described in, say, PhysRevC.90.034601 (2014). dE_linPID = ((dE+E)^a-E^a)^(1/a) where a ~ 1.68 is chosen empirically
float Theta=DEFAULT_NULL; //!< Laboratory polar angle of event in radians, deprecated
float Phi=DEFAULT_NULL; //!< Lab azimuthal angle of event in radians, deprecated
//Helpful indices to make dE-E plots
std::string type; //!< "endcap" vs "barrel"
//!< Identify the position of the detector in the barrel, usually in accordance with the channel map: say we might learn detector is at "Quad 4" or "clk_pos 10", together with 'type'. Useful with HistPlotter class
int position=DEFAULT_NULL;
int subchdE_1=DEFAULT_NULL, subchdE_2=DEFAULT_NULL; //!< Identify the subchannels corresponding to the two sides of the dE detector. To avoid confusion, 1=strip(sx3), ring(qqq) and 2=pad(sx3), wedge(qqq)
int subchE_1=DEFAULT_NULL, subchE_2=DEFAULT_NULL; //!< Identify the subchannels corresponding to the two sides of the E detector. Same convention as above
float x=DEFAULT_NULL,y=DEFAULT_NULL,z=DEFAULT_NULL; //!< Laboratory x,y,z coordinates of the event from the E layer
float r0=DEFAULT_NULL,theta0=DEFAULT_NULL,phi0=DEFAULT_NULL; //!< vector elements from hit to origin for E layer
float r1=DEFAULT_NULL,theta1=DEFAULT_NULL,phi1=DEFAULT_NULL; //!< vector elements from hit to origin for dE layer
};
/*TODO:
* There will be some use for a class such that it stores
PhysicsEvent = <Ex, Brho, THeta4, ...orrubaevent >
* Once the 'orrubaevent' structs are made, it should be callable. like
std::vector<PhysicsEvent> getPhysicsFromVertices(Kinematics dpkin, std::vector<orrubaevent> orvec);?
* should the physics just go sit in orrubaevent? maybe orruba2024 class can have a kinematics object in it?
*/
class orruba2024 {
private:
//Class expected to be changed for each version of the analysis code
public:
bool found_trk, found_trkpresc, found_tdcq, found_s800e1, found_s800trg,
found_rf, found_gt, found_si, found_siup;
bool found_de, found_e, found_qqq, found_sx3;//orruba
long long timestamp=DEFAULT_NULL;
std::vector<type19Raw> o_rawvec;
std::array<qqq5,4> uendcapE;
std::array<qqq5,4> uendcapdE;
std::array<sx3,12> ubarrelE;
std::array<sx3,12> ubarreldE;
std::array<sx3,2> dbarrelE;
//Results after post-processing, including possible multiplicities
std::vector<orrubaevent> events;
double target_z_offset;
//void initialize(const std::string & filename1, const std::string& filename2, const std::string& filename3);
float tdc_trk = DEFAULT_NULL;
float tdc_trksi = DEFAULT_NULL; //trackerpr+si stops are combined into one channel
float tdc_trkp = DEFAULT_NULL;
float tdc_q = DEFAULT_NULL;
float tdc_s800e1 = DEFAULT_NULL;
float tdc_s800trg = DEFAULT_NULL;
float tdc_rf = DEFAULT_NULL;
float tdc_rf_unwrap = DEFAULT_NULL;
float tdc_gt = DEFAULT_NULL;
float tdc_si = DEFAULT_NULL;
float tdc_siup = DEFAULT_NULL;
orruba2024(const std::vector<type19Raw>& orvec);
void postprocess(); //generates 'events', and performs validations on freshly entered data. performs fine gainmatching for front-back-pairs
void print() const {
std::cout << Form("TDCs\n trk:%1.4f\ntrkp:%1.4f\nq:%1.4f\ns800e1:%1.4f\ns800trg:%1.4f\nrf:%1.4f\nrfuw:%1.4f\ngt:%1.4f\nsi:%1.4f\nsiup:%1.4f\n-----\nevents_size:%lu\ntimestamp:%lld\nfound_de:%d, found_e:%d\n-------\n-------\n",
tdc_trk, tdc_trkp, tdc_q, tdc_s800e1, tdc_s800trg, tdc_rf, tdc_rf_unwrap, tdc_gt, tdc_si, tdc_siup, events.size(), timestamp, found_de, found_e) << std::endl;
}
};
class trackingdet {
public:
double timestamp=DEFAULT_NULL;
//TODO: Convert all to std::array
std::vector<float> xwires[MAXNWIRES_TRACK];
std::vector<float> ywires[MAXNWIRES_TRACK];
std::vector<float> xwiresf[MAXNWIRES_TRACK];
std::vector<float> ywiresf[MAXNWIRES_TRACK];
std::vector<float> xwiresf_nn[MAXNWIRES_TRACK];
std::vector<float> ywiresf_nn[MAXNWIRES_TRACK];
std::vector<float> xtimes[MAXNWIRES_TRACK];
std::vector<float> ytimes[MAXNWIRES_TRACK];
std::vector<float> xtimesf[MAXNWIRES_TRACK];
std::vector<float> ytimesf[MAXNWIRES_TRACK];
std::vector<float> cathode;
int multx; //how many x-wires fired?
int multy; //how many y-wires fired?
int multxf; //how many filtered x-wires fired?
int multyf; //how many filtered y-wires fired?
int multxt; //how many x-tdcwires fired?
int multyt; //how many y-tdcwires fired?
int multxtf; //how many x-tdcwires fired in window?
int multytf; //how many y-tdcwires fired in window?
float tot_cathode=0;
float tot_x=0;
float tot_y=0;
float tot_anode=0;
//list of x and y wires fired above energy threshold, within timing gate window
std::set<int> list_ywires;
std::set<int> list_xwires;
std::set<int> list_ytwires;
std::set<int> list_xtwires;
//position of the vertex estimated by up to 2 neighbouring wires firing together within window
double xpos=DEFAULT_NULL;
double ypos=DEFAULT_NULL;
bool clean_event = false;
int maxnx=-124, maxny=-124;
int nnx = 0; //nearest neighbour x wires set this to +/- 1 if present w.r.t. wire maxnx
int nny = 0; //nearest neighbour y wires set this to +/- 1 if present w.r.t wire maxny
bool clean_event_no_timing = false;
bool clean_single_xy_event = false;
bool clean_single_xy_event_no_timing = false;
void Reset() {
/***
Resets all data members.
**/
cathode.clear();
for(int i=0; i<MAXNWIRES_TRACK; i++) {
xwires[i].clear();
ywires[i].clear();
xwiresf[i].clear();
ywiresf[i].clear();
xwiresf_nn[i].clear();
ywiresf_nn[i].clear();
xtimes[i].clear();
ytimes[i].clear();
xtimesf[i].clear();
ytimesf[i].clear();
}
list_xwires.clear();
list_ywires.clear();
list_xtwires.clear();
list_ytwires.clear();
nnx = 0;
nny = 0;
clean_event_no_timing = false;
clean_event = false; //x, y both fire above thresh, xt, yt present within broad coinc window
xpos=DEFAULT_NULL;
ypos=DEFAULT_NULL;
maxnx=-124;
maxny=-124;
multx=0; //how many x-wires fired?
multy=0; //how many y-wires fired?
multxf=0; //how many filt x-wires fired?
multyf=0; //how many filt y-wires fired?
multxt=0; //how many tdc x-wires fired?
multyt=0; //how many tdc y-wires fired?
multxtf=0; //how many tdc x-wires fired?
multytf=0; //how many tdc y-wires fired?
}
trackingdet() {
Reset();
};
trackingdet(const std::vector<type19Raw>& orvec);
};
const float alpha = 0.0;
int matchchantype(unsigned short chan, const std::array<orruba_params,MAX_ORRUBA_CHANS>& index, const std::string& label);
void initialize_orruba(const std::string & filename1, const std::string& filename2, const std::string& filename3, const std::string& filename4);//,
int parse_orruba_data(const unsigned short* buffer, int32_t length, type19Raw& oraw_event);
#endif

330
mapping.h
View File

@ -12,213 +12,261 @@
#include <TMath.h> #include <TMath.h>
const std::map<int, unsigned short> board = { const std::map<int, unsigned short> board = {
{0, 17122}, // id, sn {0, 17122}, // id, sn
{1, 17123}, {1, 17123},
{2, 22320}, {2, 22320},
{3, 22130}, {3, 22130},
{4, 22129}, {4, 22129},
{5, 15529}, {5, 15529},
{6, 15528}, {6, 15528},
{7, 334}, // {7,89},
{8, 379}, {7, 334},
{9, 325}, {8, 379},
{10, 405} {9, 325},
}; {10, 405}};
const int nBd = board.size(); const int nBd = board.size();
const int nV1740 = 7; const int nV1740 = 7;
const int nV1725 = 3; const int nV1725 = 4;
//+++++++++++++++++++ detID; //+++++++++++++++++++ detID;
// The detectors are seperated into 2 type: SuperX3, QQQ, and PC // The detectors are seperated into 2 type: SuperX3, QQQ, and PC
// the SuperX3 has 24 detectors for each kind, wach detector has 12 channels // the SuperX3 has 24 detectors for each kind, wach detector has 12 channels
// the QQQ has 4 detectors for each kind, each detector has 32 channels // the QQQ has 4 detectors for each kind, each detector has 32 channels
// the PC has 2 types, anode and cathode, each has 24 channels // the PC has 2 types, anode and cathode, each has 24 channels
// the MISC has 6 channels, the lollipop IC and siliscon followed by the hotneedle IC, as well as the Rf and MCP
// The detID = Type * 10000 + index * 100 + channel // The detID = Type * 10000 + index * 100 + channel
// fro example, detID(superX3-8, ch-7) = 00807 // fro example, detID(superX3-8, ch-7) = 00807
// use the GenMapping() to get that // use the GenMapping() to get that
const std::vector<int> mapping = { const std::vector<int> mapping = {
//================== 17122 //================== 17122
806, 807, 804, 805, 803, 802, 801, 800, 1006, 1007, 1004, 1005, 1003, 1002, 1001, 1000, 806, 807, 804, 805, 803, 802, 801, 800, 1006, 1007, 1004, 1005, 1003, 1002, 1001, 1000,
606, 607, 604, 605, 603, 602, 601, 600, 1106, 1107, 1104, 1105, 1103, 1102, 1101, 1100, 606, 607, 604, 605, 603, 602, 601, 600, 1106, 1107, 1104, 1105, 1103, 1102, 1101, 1100,
711, 710, 709, 708, 911, 910, 909, 908, 1011, 1010, 1009, 1008, 811, 810, 809, 808, 711, 710, 709, 708, 911, 910, 909, 908, 1011, 1010, 1009, 1008, 811, 810, 809, 808,
706, 707, 704, 705, 703, 702, 701, 700, 906, 907, 904, 905, 903, 902, 901, 900, 706, 707, 704, 705, 703, 702, 701, 700, 906, 907, 904, 905, 903, 902, 901, 900,
//================== 17123 //================== 17123
1406, 1407, 1404, 1405, 1403, 1402, 1401, 1400, 1606, 1607, 1604, 1605, 1603, 1602, 1601, 1600, 1406, 1407, 1404, 1405, 1403, 1402, 1401, 1400, 1606, 1607, 1604, 1605, 1603, 1602, 1601, 1600,
1306, 1307, 1304, 1305, 1303, 1302, 1301, 1300, 1506, 1507, 1504, 1505, 1503, 1502, 1501, 1500, 1306, 1307, 1304, 1305, 1303, 1302, 1301, 1300, 1506, 1507, 1504, 1505, 1503, 1502, 1501, 1500,
1311, 1310, 1309, 1308, 1711, 1710, 1709, 1708, 1611, 1610, 1609, 1608, 1411, 1410, 1409, 1408, 1311, 1310, 1309, 1308, 1711, 1710, 1709, 1708, 1611, 1610, 1609, 1608, 1411, 1410, 1409, 1408,
1206, 1207, 1204, 1205, 1203, 1202, 1201, 1200, 1706, 1707, 1704, 1705, 1703, 1702, 1701, 1700, 1206, 1207, 1204, 1205, 1203, 1202, 1201, 1200, 1706, 1707, 1704, 1705, 1703, 1702, 1701, 1700,
//================== 22320 //================== 22320
6, 7, 4, 5, 3, 2, 1, 0, 506, 507, 504, 505, 503, 502, 501, 500, 6, 7, 4, 5, 3, 2, 1, 0, 506, 507, 504, 505, 503, 502, 501, 500,
111, 110, 109, 108, 311, 310, 309, 308, 411, 410, 409, 408, 211, 210, 209, 208, 111, 110, 109, 108, 311, 310, 309, 308, 411, 410, 409, 408, 211, 210, 209, 208,
206, 207, 204, 205, 203, 202, 201, 200, 406, 407, 404, 405, 403, 402, 401, 400, 206, 207, 204, 205, 203, 202, 201, 200, 406, 407, 404, 405, 403, 402, 401, 400,
106, 107, 104, 105, 103, 102, 101, 100, 306, 307, 304, 305, 303, 302, 301, 300, 106, 107, 104, 105, 103, 102, 101, 100, 306, 307, 304, 305, 303, 302, 301, 300,
//================== 22130 //================== 22130
1911, 1910, 1909, 1908, 2111, 2110, 2109, 2108, 2211, 2210, 2209, 2208, 2011, 2010, 2009, 2008, 1911, 1910, 1909, 1908, 2111, 2110, 2109, 2108, 2211, 2210, 2209, 2208, 2011, 2010, 2009, 2008,
11, 10, 9, 8, 511, 510, 509, 508, 611, 610, 609, 608, 1111, 1110, 1109, 1108, 11, 10, 9, 8, 511, 510, 509, 508, 611, 610, 609, 608, 1111, 1110, 1109, 1108,
2006, 2007, 2004, 2005, 2003, 2002, 2001, 2000, 2206, 2207, 2204, 2205, 2203, 2202, 2201, 2200, 2006, 2007, 2004, 2005, 2003, 2002, 2001, 2000, 2206, 2207, 2204, 2205, 2203, 2202, 2201, 2200,
1906, 1907, 1904, 1905, 1903, 1902, 1901, 1900, 2106, 2107, 2104, 2105, 2103, 2102, 2101, 2100, 1906, 1907, 1904, 1905, 1903, 1902, 1901, 1900, 2106, 2107, 2104, 2105, 2103, 2102, 2101, 2100,
//================== 22129 //================== 22129
1806, 1807, 1804, 1805, 1803, 1802, 1801, 1800, 2306, 2307, 2304, 2305, 2303, 2302, 2301, 2300, 1806, 1807, 1804, 1805, 1803, 1802, 1801, 1800, 2306, 2307, 2304, 2305, 2303, 2302, 2301, 2300,
10016, 10017, 10018, 10019, 10020, 10021, 10022, 10023, 10024, 10025, 10026, 10027, 10028, 10029, 10030, 10031, 10031, 10030, 10029, 10028, 10027, 10026, 10025, 10024, 10023, 10022, 10021, 10020, 10019, 10018, 10017, 10016,
10116, 10117, 10118, 10119, 10120, 10121, 10122, 10123, 10124, 10125, 10126, 10127, 10128, 10129, 10130, 10131, // 10016, 10017, 10018, 10019, 10020, 10021, 10022, 10023, 10024, 10025, 10026, 10027, 10028, 10029, 10030, 10031,
10015, 10014, 10013, 10012, 10011, 10010, 10009, 10008, 10007, 10006, 10005, 10004, 10003, 10002, 10001, 10000, 10116, 10117, 10118, 10119, 10120, 10121, 10122, 10123, 10124, 10125, 10126, 10127, 10128, 10129, 10130, 10131,
//================== 15529 10015, 10014, 10013, 10012, 10011, 10010, 10009, 10008, 10007, 10006, 10005, 10004, 10003, 10002, 10001, 10000,
10231, 10230, 10229, 10228, 10227, 10226, 10225, 10224, 10223, 10222, 10221, 10220, 10219, 10218, 10217, 10216, //================== 15529
10115, 10114, 10113, 10112, 10111, 10110, 10109, 10108, 10107, 10106, 10105, 10104, 10103, 10102, 10101, 10100, 10231, 10230, 10229, 10228, 10227, 10226, 10225, 10224, 10223, 10222, 10221, 10220, 10219, 10218, 10217, 10216,
10315, 10314, 10313, 10312, 10311, 10310, 10309, 10308, 10307, 10306, 10305, 10304, 10303, 10302, 10301, 10300, 10100, 10101, 10102, 10103, 10104, 10105, 10106, 10107, 10108, 10109, 10110, 10111, 10112, 10113, 10114, 10115,
10215, 10214, 10213, 10212, 10211, 10210, 10209, 10208, 10207, 10206, 10205, 10204, 10203, 10202, 10201, 10200, // 10115, 10114, 10113, 10112, 10111, 10110, 10109, 10108, 10107, 10106, 10105, 10104, 10103, 10102, 10101, 10100,
//================== 15528 10300, 10301, 10302, 10303, 10304, 10305, 10306, 10307, 10308, 10309, 10310, 10311, 10312, 10313, 10314, 10315,
10316, 10317, 10318, 10319, 10320, 10321, 10322, 10323, 10324, 10325, 10326, 10327, 10328, 10329, 10330, 10331, // 10315, 10314, 10313, 10312, 10311, 10310, 10309, 10308, 10307, 10306, 10305, 10304, 10303, 10302, 10301, 10300,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10215, 10214, 10213, 10212, 10211, 10210, 10209, 10208, 10207, 10206, 10205, 10204, 10203, 10202, 10201, 10200,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //================== 15528
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10316, 10317, 10318, 10319, 10320, 10321, 10322, 10323, 10324, 10325, 10326, 10327, 10328, 10329, 10330, 10331,
//================== 334 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20116, 20117, 20118, 20119, 20120, 20121, 20122, 20123, 20016, 20017, 20018, 20019, 20020, 20021, 20022, 20023, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//================== 379 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20000, 20001, 20002, 20003, 20004, 20005, -1, 20007, 20008, -1, 20010, 20011, 20012, 20013, 20014, 20015, //================== 89
//================== 325 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
20100, 20101, 20102, 20103, 20104, 20105, 20106, 20107, 20108, 20109, 20110, 20111, 20112, 20113, 20114, 20115, // 30004, -1, 30003, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//================== 405 //================== 334
20006, -1, -1, 20009, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 20116, 20117, 20118, 20119, -1, 20121, 20122, 20123, 20016, 20017, 20018, -1, 20020, 20021, 20022, 20023,
//================== 379
-1, 20001, 20002, 20003, 20004, 20005, -1, 20007, 20008, -1, 20010, 20011, 20012, 20013, 20014, 20015,
//================== 325
20100, 20101, 20102, 20103, 20104, 20105, 20106, 20107, 20108, 20109, 20110, 20111, 20112, -1, 20114, 20115,
//================== 405
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
20006, -1, 30005, 20009, -1, 20120, 20000, 20019, 20113, 30000, 30004, 30001, 30002, -1, 30003, -1};
}; // MCP moved from channel 1 to 2 after Run number 322
// MCP and Rf moved to ch 0 and 1 after Run number after Run282
void PrintMapping(){ // moved back to ch
void PrintMapping()
{
int digiID = 0; int digiID = 0;
int count = 0; int count = 0;
printf("==================== ID-MAP: \n"); printf("==================== ID-MAP: \n");
printf("%11s|", ""); for(int i = 0 ; i < 16; i++ ) printf("%7d|", i); printf("%11s|", "");
for (int i = 0; i < 16; i++)
printf("%7d|", i);
printf("\n"); printf("\n");
for(int i = 0 ; i < 12 + 16*8; i++ ) printf("-"); for (int i = 0; i < 12 + 16 * 8; i++)
for(size_t i = 0 ; i < mapping.size(); i ++){ printf("-");
if( (i) % 16 == 0 ) { for (size_t i = 0; i < mapping.size(); i++)
{
if ((i) % 16 == 0)
{
printf("\n"); printf("\n");
if( digiID < nBd ){ if (digiID < nBd)
if( board.at(digiID) > 1000 ) { {
if( count == 3 ) digiID ++; if (board.at(digiID) > 1000)
if( i % 64 == 0 ) { {
if (count == 3)
digiID++;
if (i % 64 == 0)
{
printf("%11d|", board.at(digiID)); printf("%11d|", board.at(digiID));
count = 0; count = 0;
} }
}else{ }
if( count == 1 ) digiID ++; else
if( i % 16 == 0 ) { {
if (count == 1)
digiID++;
if (i % 16 == 0)
{
printf("%11d|", board.at(digiID)); printf("%11d|", board.at(digiID));
count = 0; count = 0;
} }
} }
} }
if( count != 0) printf("%11s|", ""); if (count != 0)
count ++; printf("%11s|", "");
count++;
} }
int typeID = mapping[i] / 10000; int typeID = mapping[i] / 10000;
int detID = (mapping[i] - typeID*10000 )/100; int detID = (mapping[i] - typeID * 10000) / 100;
int ch = mapping[i] - typeID*10000 - detID * 100; int ch = mapping[i] - typeID * 10000 - detID * 100;
if( mapping[i] == -1 ) { if (mapping[i] == -1)
{
printf("%7s|", ""); printf("%7s|", "");
}
else
{
}else{ if (typeID == 0)
{ // SX3
if( typeID == 0){ // SX3
printf("\033[36m%3d(%2d)\033[0m|", detID, ch); printf("\033[36m%3d(%2d)\033[0m|", detID, ch);
}
}else if( typeID == 1){ // QQQ else if (typeID == 1)
{ // QQQ
printf("\033[91m%3d(%2d)\033[0m|", detID, ch); printf("\033[91m%3d(%2d)\033[0m|", detID, ch);
}
}else if( typeID == 2){ // PC else if (typeID == 2)
{ // PC
printf("\033[35m%3d(%2d)\033[0m|", detID, ch); printf("\033[35m%3d(%2d)\033[0m|", detID, ch);
}
else if (typeID == 3)
{ // MISC
}else{ printf("\033[33m%3d(%2d)\033[0m|", detID, ch);
} }
} }
} }
printf("\n"); printf("\n");
for(int i = 0 ; i < 12 + 16*8; i++ ) printf("-"); for (int i = 0; i < 12 + 16 * 8; i++)
printf("-");
printf("\n"); printf("\n");
} }
void GenMapping(std::string mapFile)
void GenMapping(std::string mapFile){ {
std::vector<int> map; std::vector<int> map;
std::ifstream inputFile(mapFile); // Replace "your_file.txt" with the actual file path
std::ifstream inputFile(mapFile); // Replace "your_file.txt" with the actual file path if (!inputFile.is_open())
{
if (!inputFile.is_open()) {
printf("Error: Could not open the file (%s).\n", mapFile.c_str()); printf("Error: Could not open the file (%s).\n", mapFile.c_str());
return ; return;
} }
std::string line; std::string line;
// Read the file line by line // Read the file line by line
while (std::getline(inputFile, line)) { while (std::getline(inputFile, line))
{
std::vector<std::string> words; std::vector<std::string> words;
std::istringstream iss(line); std::istringstream iss(line);
// Extract words from the current line // Extract words from the current line
while (true) { while (true)
{
std::string word; std::string word;
if (!(iss >> word)) break; // Break if there are no more words if (!(iss >> word))
break; // Break if there are no more words
word.erase(std::remove_if(word.begin(), word.end(), ::isspace), word.end()); word.erase(std::remove_if(word.begin(), word.end(), ::isspace), word.end());
words.push_back(word); words.push_back(word);
} }
if( atoi(words[0].c_str()) % 16 == 0 ) printf("=================\n"); if (atoi(words[0].c_str()) % 16 == 0)
printf("=================\n");
int detID = atoi(words[1].c_str()) * 100;
int detID = atoi(words[1].c_str())*100; if (words.size() < 5)
if(words.size() < 5 ) printf(" hahhahha %s\n", line.c_str()); printf(" hahhahha %s\n", line.c_str());
if( words[2] == "BARREL" ) { if (words[2] == "BARREL")
if( words[3] == "FRONTDOWN" ){ {
if (words[3] == "FRONTDOWN")
{
int chID = atoi(words[4].c_str()); int chID = atoi(words[4].c_str());
if( chID % 2 != 0 ) chID -= 1; if (chID % 2 != 0)
chID -= 1;
detID += chID; detID += chID;
} }
if( words[3] == "FRONTUP" ){ if (words[3] == "FRONTUP")
{
int chID = atoi(words[4].c_str()); int chID = atoi(words[4].c_str());
if( chID % 2 == 0 ) chID += 1; if (chID % 2 == 0)
chID += 1;
detID += chID; detID += chID;
} }
if( words[3] == "BACK") detID += atoi(words[4].c_str()) + 8; if (words[3] == "BACK")
detID += atoi(words[4].c_str()) + 8;
} }
if( words[2] == "FQQQ" ) { if (words[2] == "FQQQ")
{
detID += 10000; detID += 10000;
if( words[3] == "WEDGE") detID += atoi(words[4].c_str()); if (words[3] == "WEDGE")
if( words[3] == "RING") detID += atoi(words[4].c_str()) + 16; detID += atoi(words[4].c_str());
if (words[3] == "RING")
detID += atoi(words[4].c_str()) + 16;
} }
if( words[2] == "PC" ) { if (words[2] == "PC")
{
detID += 20000; detID += 20000;
if( words[3] == "ANODE") detID += atoi(words[4].c_str()); if (words[3] == "ANODE")
if( words[3] == "CATHODE") detID += 100 + atoi(words[4].c_str()); detID += atoi(words[4].c_str());
if (words[3] == "CATHODE")
detID += 100 + atoi(words[4].c_str());
} }
if( words[2] == "blank") { if(words[2] == "MISC")
{
detID += 30000;
}
if (words[2] == "blank")
{
detID = -1; detID = -1;
} }
@ -234,29 +282,42 @@ void GenMapping(std::string mapFile){
int digiID = 0; int digiID = 0;
int count = 0; int count = 0;
printf("===============================\n"); printf("===============================\n");
for( size_t i = 0; i < ((map.size() +15)/16) * 16; i++){ for (size_t i = 0; i < ((map.size() + 15) / 16) * 16; i++)
if( i % 16 == 0) { {
if (i % 16 == 0)
{
printf("\n"); printf("\n");
if( digiID < nBd ){ if (digiID < nBd)
if( board.at(digiID) > 1000 ) { {
if( count == 3 ) digiID ++; if (board.at(digiID) > 1000)
if( i % 64 == 0 ) { {
if (count == 3)
digiID++;
if (i % 64 == 0)
{
printf(" //================== %d\n", board.at(digiID)); printf(" //================== %d\n", board.at(digiID));
count = 0; count = 0;
} }
}else{ }
if( count == 1 ) digiID ++; else
if( i % 16 == 0 ) { {
if (count == 1)
digiID++;
if (i % 16 == 0)
{
printf(" //================== %d\n", board.at(digiID)); printf(" //================== %d\n", board.at(digiID));
count = 0; count = 0;
} }
} }
} }
count ++; count++;
} }
if( i < map.size() ){ if (i < map.size())
{
printf(" %5d,", map[i]); printf(" %5d,", map[i]);
}else{ }
else
{
printf(" %5d,", -1); printf(" %5d,", -1);
} }
} }
@ -265,13 +326,14 @@ void GenMapping(std::string mapFile){
printf("sorting mapping and see if there any repeated\n"); printf("sorting mapping and see if there any repeated\n");
std::sort(map.begin(), map.end()); std::sort(map.begin(), map.end());
for( size_t i = 1; i < map.size(); i++){ for (size_t i = 1; i < map.size(); i++)
if( map[i] == -1 ) continue; {
if( map[i] == map[i-1] ) printf("%5d \n", map[i]); if (map[i] == -1)
continue;
if (map[i] == map[i - 1])
printf("%5d \n", map[i]);
} }
printf("=========== Done. if nothing show, no repeat. \n"); printf("=========== Done. if nothing show, no repeat. \n");
} }
#endif #endif

View File

@ -302,22 +302,22 @@
301 1 FQQQ RING 13 301 1 FQQQ RING 13
302 1 FQQQ RING 14 302 1 FQQQ RING 14
303 1 FQQQ RING 15 303 1 FQQQ RING 15
304 1 FQQQ WEDGE 15 304 1 FQQQ WEDGE 0
305 1 FQQQ WEDGE 14 305 1 FQQQ WEDGE 1
306 1 FQQQ WEDGE 13 306 1 FQQQ WEDGE 2
307 1 FQQQ WEDGE 12 307 1 FQQQ WEDGE 3
308 1 FQQQ WEDGE 11 308 1 FQQQ WEDGE 4
309 1 FQQQ WEDGE 10 309 1 FQQQ WEDGE 5
310 1 FQQQ WEDGE 9 310 1 FQQQ WEDGE 6
311 1 FQQQ WEDGE 8 311 1 FQQQ WEDGE 7
312 1 FQQQ WEDGE 7 312 1 FQQQ WEDGE 8
313 1 FQQQ WEDGE 6 313 1 FQQQ WEDGE 9
314 1 FQQQ WEDGE 5 314 1 FQQQ WEDGE 10
315 1 FQQQ WEDGE 4 315 1 FQQQ WEDGE 11
316 1 FQQQ WEDGE 3 316 1 FQQQ WEDGE 12
317 1 FQQQ WEDGE 2 317 1 FQQQ WEDGE 13
318 1 FQQQ WEDGE 1 318 1 FQQQ WEDGE 14
319 1 FQQQ WEDGE 0 319 1 FQQQ WEDGE 15
320 2 FQQQ RING 15 320 2 FQQQ RING 15
321 2 FQQQ RING 14 321 2 FQQQ RING 14
322 2 FQQQ RING 13 322 2 FQQQ RING 13
@ -366,22 +366,22 @@
365 2 FQQQ WEDGE 2 365 2 FQQQ WEDGE 2
366 2 FQQQ WEDGE 1 366 2 FQQQ WEDGE 1
367 2 FQQQ WEDGE 0 367 2 FQQQ WEDGE 0
368 3 FQQQ WEDGE 15 368 3 FQQQ WEDGE 0
369 3 FQQQ WEDGE 14 369 3 FQQQ WEDGE 1
370 3 FQQQ WEDGE 13 370 3 FQQQ WEDGE 2
371 3 FQQQ WEDGE 12 371 3 FQQQ WEDGE 3
372 3 FQQQ WEDGE 11 372 3 FQQQ WEDGE 4
373 3 FQQQ WEDGE 10 373 3 FQQQ WEDGE 5
374 3 FQQQ WEDGE 9 374 3 FQQQ WEDGE 6
375 3 FQQQ WEDGE 8 375 3 FQQQ WEDGE 7
376 3 FQQQ WEDGE 7 376 3 FQQQ WEDGE 8
377 3 FQQQ WEDGE 6 377 3 FQQQ WEDGE 9
378 3 FQQQ WEDGE 5 378 3 FQQQ WEDGE 10
379 3 FQQQ WEDGE 4 379 3 FQQQ WEDGE 11
380 3 FQQQ WEDGE 3 380 3 FQQQ WEDGE 12
381 3 FQQQ WEDGE 2 381 3 FQQQ WEDGE 13
382 3 FQQQ WEDGE 1 382 3 FQQQ WEDGE 14
383 3 FQQQ WEDGE 0 383 3 FQQQ WEDGE 15
384 3 FQQQ RING 0 384 3 FQQQ RING 0
385 3 FQQQ RING 1 385 3 FQQQ RING 1
386 3 FQQQ RING 2 386 3 FQQQ RING 2

48
pc_energy_calibration.dat Normal file
View File

@ -0,0 +1,48 @@
0 7.569000E-06 0.000000E+00 1
1 1.283082E-05 0.000000E+00 1
2 1.283082E-05 0.000000E+00 1
3 1.283082E-05 0.000000E+00 1
4 1.283082E-05 0.000000E+00 1
5 1.496409E-05 0.000000E+00 2
6 2.036882E-05 0.000000E+00 1
7 1.124799E-05 0.000000E+00 1
8 1.123432E-05 0.000000E+00 1
9 3.333333E-01 0.000000E+00 3
10 1.292001E-05 0.000000E+00 1
11 8.787520E-06 0.000000E+00 1
12 3.333333E-01 0.000000E+00 3
13 7.867300E-06 0.000000E+00 1
14 6.707640E-06 0.000000E+00 1
15 8.515706E-06 0.000000E+00 1
16 1.041633E-05 0.000000E+00 1
17 1.041633E-05 0.000000E+00 1
18 1.283082E-05 0.000000E+00 1
19 9.043133E-06 0.000000E+00 2
20 1.046743E-05 0.000000E+00 1
21 1.046743E-05 0.000000E+00 2
22 1.047560E-05 0.000000E+00 2
23 1.283082E-05 0.000000E+00 2
24 1.008216E-05 0.000000E+00 1
25 1.244045E-05 0.000000E+00 1
26 1.162146E-05 0.000000E+00 1
27 1.837130E-05 0.000000E+00 1
28 1.490705E-05 0.000000E+00 1
29 1.218593E-05 0.000000E+00 1
30 1.193124E-05 0.000000E+00 1
31 1.169320E-05 0.000000E+00 1
32 1.204609E-05 0.000000E+00 1
33 9.622476E-06 0.000000E+00 1
34 1.010416E-05 0.000000E+00 1
35 9.946100E-06 0.000000E+00 1
36 1.245206E-05 0.000000E+00 1
37 2.004189E-05 0.000000E+00 2
38 1.101200E-05 0.000000E+00 1
39 2.013155E-05 0.000000E+00 1
40 1.503905E-05 0.000000E+00 1
41 1.695527E-05 0.000000E+00 1
42 1.255106E-05 0.000000E+00 1
43 1.885628E-05 0.000000E+00 1
44 3.987430E-05 0.000000E+00 2
45 9.909176E-06 0.000000E+00 1
46 9.432880E-06 0.000000E+00 1
47 1.103287E-05 0.000000E+00 1

67
pccal/anode_gainmatch.C Normal file
View File

@ -0,0 +1,67 @@
void anode_gainmatch(){
TFile *f = new TFile("../results_run16.root");
TH2F *pc_index_h2d = (TH2F*)(f->Get("hRawPC/PC_Index_Vs_Energy"));
std::cout << pc_index_h2d << std::endl;
TCanvas c("c1","c1",0,0,1600,800);
//TCanvas c_g("cg","cg",0,900,400,400);
c.Divide(2,1);
auto c1=c.cd(1);
pc_index_h2d->Draw("COLZ");
pc_index_h2d->GetYaxis()->SetRangeUser(240,5000);
auto c2=c.cd(2);
c2->SetLogy();
TH1F *h_1d=NULL;
int bin_index=1;
std::vector<std::vector<double>> all_peaks;
std::vector<int> found_wire_list;
while(bin_index<=24) {
h_1d=(TH1F*)(pc_index_h2d->ProjectionY("_py",bin_index,bin_index));
auto c1 = c.cd(1);
TBox box(pc_index_h2d->GetXaxis()->GetBinLowEdge(bin_index),0,pc_index_h2d->GetXaxis()->GetBinUpEdge(bin_index),pc_index_h2d->GetYaxis()->GetXmax());
box.SetFillColorAlpha(kYellow+3,0.3);
box.Draw("SAME");
c1->Modified(); c1->Update();
//while(c1->WaitPrimitive());
TSpectrum s;
auto c2 = c.cd(2);
h_1d->Draw();
c2->Modified(); c2->Update();
int npeaks = s.Search(h_1d,8,"",0.02); std::cout << npeaks << std::endl;
if(npeaks>=3) {
std::vector<double> xpeaks(s.GetPositionX(),s.GetPositionX()+npeaks);
std::sort(xpeaks.begin(),xpeaks.end(),std::greater());
found_wire_list.push_back((int)pc_index_h2d->GetXaxis()->GetBinCenter(bin_index));
all_peaks.push_back(xpeaks);
}
while(c2->WaitPrimitive());
bin_index++;
}
c.cd(2)->SetLogy(kFALSE);
gStyle->SetOptFit(1111);
std::ofstream outfile("anode_gm_coeffs.dat");
outfile << found_wire_list.at(0) << " "
<< 1.0 << " "
<< 0.0 << std::endl;
for(int i=0; i<all_peaks.size(); i++){
if(i==1) continue;
TGraph g(all_peaks.at(i).size(), all_peaks.at(i).data(), all_peaks.at(1).data());
auto c2 = c.cd(2);
g.SetMarkerStyle(20);
//g.Print();
g.Draw("AP");
g.Fit("pol1");
outfile << found_wire_list.at(i) << " "
<< ((TF1*)g.FindObject("pol1"))->GetParameter(1) << " "
<< ((TF1*)g.FindObject("pol1"))->GetParameter(0) << std::endl;
c2->Modified();
c2->Update();
while(c2->WaitPrimitive());
}
outfile.close();
f->Close();
return;
}

24
pccal/anode_gm_coeffs.dat Normal file
View File

@ -0,0 +1,24 @@
0 1 0
0 0.937314 -16.871
2 0.965461 -1.54376
3 0.926501 -3.27662
4 0.905634 2.54577
5 0.905634 -11.0387
6 0.853919 6.23079
7 0.945588 -9.54044
8 0.884454 -11.8262
9 0.922501 -3.42538
10 0.903053 9.28069
11 0.914653 9.87642
12 0.965332 13.2526
13 0.923847 -3.41775
14 0.93845 25.9901
15 0.955424 12.324
16 0.95116 4.99595
17 0.910745 2.86648
18 0.941376 4.57217
19 0.871622 932.111
20 1.00624 7.86358
21 0.969834 -45.001
22 0.89304 -31.5635
23 0.933226 4.02193

69
pccal/cathode_gainmatch.C Normal file
View File

@ -0,0 +1,69 @@
void cathode_gainmatch(){
TFile *f = new TFile("../results_run17.root");
TH2F *pc_index_h2d = (TH2F*)(f->Get("hRawPC/PC_Index_Vs_Energy"));
std::cout << pc_index_h2d << std::endl;
TCanvas c("c1","c1",0,0,1600,800);
//TCanvas c_g("cg","cg",0,900,400,400);
c.Divide(2,1);
auto c1=c.cd(1);
pc_index_h2d->Draw("COLZ");
pc_index_h2d->GetYaxis()->SetRangeUser(600,pc_index_h2d->GetYaxis()->GetXmax());
auto c2=c.cd(2);
c2->SetLogy();
TH1F *h_1d=NULL;
int bin_index=25;
std::vector<double> pulser_heights = {0.01,0.05,0.1,0.15,0.2,0.25,0.3,0.5};
std::vector<std::vector<double>> all_peaks;
std::vector<int> found_wire_list;
while(bin_index<=48) {
h_1d=(TH1F*)(pc_index_h2d->ProjectionY("_py",bin_index,bin_index));
auto c1 = c.cd(1);
TBox box(pc_index_h2d->GetXaxis()->GetBinLowEdge(bin_index),0,pc_index_h2d->GetXaxis()->GetBinUpEdge(bin_index),pc_index_h2d->GetYaxis()->GetXmax());
box.SetFillColorAlpha(kYellow+3,0.3);
box.Draw("SAME");
c1->Modified(); c1->Update();
//while(c1->WaitPrimitive());
TSpectrum s;
auto c2 = c.cd(2);
h_1d->Draw();
c2->Modified(); c2->Update();
int npeaks = s.Search(h_1d,20,"",0.1); std::cout << npeaks << std::endl;
if(npeaks==8) {
std::vector<double> xpeaks(s.GetPositionX(),s.GetPositionX()+npeaks);
for(int i=0; i<8; i++) {
std::cout << pc_index_h2d->GetXaxis()->GetBinCenter(bin_index) << " " << xpeaks.at(i) << " " << xpeaks.at(i)/pulser_heights.at(i) << std::endl;
}
std::sort(xpeaks.begin(),xpeaks.end(),std::greater());
found_wire_list.push_back((int)pc_index_h2d->GetXaxis()->GetBinCenter(bin_index));
all_peaks.push_back(xpeaks);
}
while(c2->WaitPrimitive());
bin_index++;
}
c.cd(2)->SetLogy(kFALSE);
gStyle->SetOptFit(1111);
std::ofstream outfile("cathode_gm_coeffs.dat");
outfile << found_wire_list.at(0) << " "
<< 1.0 << " "
<< 0.0 << std::endl;
for(int i=1; i<all_peaks.size(); i++){
TGraph g(all_peaks.at(i).size(), all_peaks.at(i).data(), all_peaks.at(0).data());
auto c2 = c.cd(2);
g.SetMarkerStyle(20);
//g.Print();
g.Draw("AP");
g.Fit("pol1");
outfile << found_wire_list.at(i) << " "
<< ((TF1*)g.FindObject("pol1"))->GetParameter(1) << " "
<< ((TF1*)g.FindObject("pol1"))->GetParameter(0) << std::endl;
c2->Modified();
c2->Update();
while(c2->WaitPrimitive());
}
outfile.close();
f->Close();
return;
}

Some files were not shown because too many files have changed in this diff Show More