Skip to content

Commit d025bc0

Browse files
committed
refactor: extract MeanMaterialBudget to standalone function
Extract duplicated MeanMaterialBudget implementations from MuDISGenerator and GenieGenerator into a standalone function with proper ALICE attribution. Changes: - Add shipgen/MeanMaterialBudget.{h,cxx} with BSD-3-Clause licence - Use complete GenieGenerator implementation (10 parameters vs 8) - Remove duplicate implementations from MuDISGenerator and GenieGenerator - Update all callers to use shipgen::MeanMaterialBudget - Add to CMakeLists.txt build configuration The standalone version includes: - Full 10-parameter interface with interaction length (mparam[8]) and maximum cross section (mparam[9]) required by FixedTargetGenerator and Pythia8Generator - Original ALICE attribution (Marian Ivanov, Andrea Dainese, Andrei Gheata) - SHiP improvements by Anupama Reghunath and Thomas Ruf - Improved error logging
1 parent 87657bd commit d025bc0

12 files changed

+289
-343
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ it in future.
212212
- Update Python code in shipDigiReco.py to use modern constructors
213213
- Bump ClassDef versions to 2 for schema evolution
214214
- Add TrackInfo to RNTuple I/O test suite
215+
- Move MeanMaterialBudget to standalone function to reduce duplication and allow proper attribution of code to ALICE
215216

216217
### Removed
217218

LICENSES/BSD-3-Clause.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Copyright (c) <year> <owner>.
2+
3+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4+
5+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6+
7+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8+
9+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10+
11+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

REUSE.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ SPDX-PackageName = "FairShip"
33
SPDX-PackageSupplier = "CERN for the benefit of the SHiP Collaboration"
44
SPDX-PackageDownloadLocation = "https://github.com/ShipSoft/FairShip"
55

6+
# MeanMaterialBudget function from ALICE AliRoot (BSD-3-Clause)
7+
[[annotations]]
8+
path = ["shipgen/MeanMaterialBudget.h", "shipgen/MeanMaterialBudget.cxx"]
9+
precedence = "aggregate"
10+
SPDX-FileCopyrightText = "ALICE Experiment at CERN, All rights reserved"
11+
SPDX-License-Identifier = "BSD-3-Clause"
12+
13+
# Default FairShip licence for all other files
614
[[annotations]]
715
path = "**"
816
precedence = "aggregate"

shipgen/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ set(SRCS
7676
FixedTargetGenerator.cxx
7777
EvtCalcGenerator.cxx
7878
TEvtGenDecayer.cxx
79-
BeamSmearingUtils.cxx)
79+
BeamSmearingUtils.cxx
80+
MeanMaterialBudget.cxx)
8081

8182
set(LINKDEF LinkDef.h)
8283
set(LIBRARY_NAME ShipGen)

shipgen/FixedTargetGenerator.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Pythia8Plugins/EvtGen.h"
1010
#include "FixedTargetGenerator.h"
1111
#include "HNLPythia8Generator.h"
12+
#include "MeanMaterialBudget.h"
1213
#include "ShipUnit.h"
1314
#include "TGeoBBox.h"
1415
#include "TGeoNode.h"
@@ -265,7 +266,7 @@ Bool_t FixedTargetGenerator::Init()
265266
end[2]=endZ;
266267
LOG(info) << "FixedTargetGenerator: Using geometry-based target coordinates startZ=" << startZ << " endZ=" << endZ;
267268
//find maximum interaction length
268-
bparam = fMaterialInvestigator->MeanMaterialBudget(start, end, mparam);
269+
bparam = shipgen::MeanMaterialBudget(start, end, mparam);
269270
maxCrossSection = mparam[9];
270271
} else if (targetName!=""){
271272
// Fallback to fragile TGeo navigation for backward compatibility
@@ -301,7 +302,7 @@ Bool_t FixedTargetGenerator::Init()
301302
end[1]=yOff;
302303
end[2]=endZ;
303304
//find maximum interaction length
304-
bparam = fMaterialInvestigator->MeanMaterialBudget(start, end, mparam);
305+
bparam = shipgen::MeanMaterialBudget(start, end, mparam);
305306
maxCrossSection = mparam[9];
306307
} else {
307308
LOG(fatal) << "No target set.";
@@ -344,7 +345,7 @@ Bool_t FixedTargetGenerator::ReadEvent(FairPrimaryGenerator* cpg)
344345
//place x,y,z uniform along path
345346
zinter = gRandom->Uniform(zinterStart,end[2]);
346347
Double_t point[3]={xOff,yOff,zinter};
347-
bparam = fMaterialInvestigator->MeanMaterialBudget(start, point, mparam);
348+
bparam = shipgen::MeanMaterialBudget(start, point, mparam);
348349
Double_t interLength = mparam[8];
349350
TGeoNode *node = gGeoManager->FindNode(point[0],point[1],point[2]);
350351
TGeoMaterial *mat = 0;

shipgen/GenieGenerator.cxx

Lines changed: 3 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "TRandom.h"
1010
#include "FairPrimaryGenerator.h"
1111
#include "GenieGenerator.h"
12+
#include "MeanMaterialBudget.h"
1213
#include "TGeoVolume.h"
1314
#include "TGeoNode.h"
1415
#include "TGeoManager.h"
@@ -67,172 +68,6 @@ Bool_t GenieGenerator::Init(const char* fileName, const int firstEvent) {
6768
return kTRUE;
6869
}
6970
// -------------------------------------------------------------------------
70-
Double_t GenieGenerator::MeanMaterialBudget(const Double_t *start, const Double_t *end, Double_t *mparam)
71-
{
72-
//
73-
// Calculate mean material budget and material properties between
74-
// the points "start" and "end".
75-
//
76-
// "mparam" - parameters used for the energy and multiple scattering
77-
// corrections:
78-
//
79-
// mparam[0] - mean density: sum(x_i*rho_i)/sum(x_i) [g/cm3]
80-
// mparam[1] - equivalent rad length fraction: sum(x_i/X0_i) [adimensional]
81-
// mparam[2] - mean A: sum(x_i*A_i)/sum(x_i) [adimensional]
82-
// mparam[3] - mean Z: sum(x_i*Z_i)/sum(x_i) [adimensional]
83-
// mparam[4] - length: sum(x_i) [cm]
84-
// mparam[5] - Z/A mean: sum(x_i*Z_i/A_i)/sum(x_i) [adimensional]
85-
// mparam[6] - number of boundary crosses
86-
// mparam[7] - maximum density encountered (g/cm^3)
87-
// mparam[8] - equivalent interaction length fraction: sum(x_i/I0_i) [adimensional]
88-
// mparam[9] - maximum cross section encountered (mbarn)
89-
//
90-
// Origin: Marian Ivanov, [email protected]
91-
//
92-
// Corrections and improvements by
93-
// Andrea Dainese, [email protected],
94-
// Andrei Gheata, [email protected]
95-
// Thomas Ruf, [email protected]
96-
//
97-
98-
mparam[0]=0; mparam[1]=1; mparam[2]=0; mparam[3]=0; mparam[4]=0;
99-
mparam[5]=0; mparam[6]=0; mparam[7]=0; mparam[8]=0; mparam[9]=0;
100-
//
101-
Double_t bparam[7]; // total parameters
102-
Double_t lparam[7]; // local parameters
103-
Double_t mbarn = 1E-3*1E-24*TMath::Na(); // cm^2 * Avogadro
104-
105-
for (Int_t i=0;i<7;i++) bparam[i]=0;
106-
107-
if (!gGeoManager) {
108-
//AliFatalClass("No TGeo\n");
109-
return 0.;
110-
}
111-
//
112-
Double_t length;
113-
Double_t dir[3];
114-
length = TMath::Sqrt((end[0]-start[0])*(end[0]-start[0])+
115-
(end[1]-start[1])*(end[1]-start[1])+
116-
(end[2]-start[2])*(end[2]-start[2]));
117-
mparam[4]=length;
118-
if (length<TGeoShape::Tolerance()) return 0.0;
119-
Double_t invlen = 1./length;
120-
dir[0] = (end[0]-start[0])*invlen;
121-
dir[1] = (end[1]-start[1])*invlen;
122-
dir[2] = (end[2]-start[2])*invlen;
123-
124-
// Initialize start point and direction
125-
TGeoNode *currentnode = 0;
126-
TGeoNode *startnode = gGeoManager->InitTrack(start, dir);
127-
if (!startnode) {
128-
//AliErrorClass(Form("start point out of geometry: x %f, y %f, z %f",
129-
// start[0],start[1],start[2]));
130-
return 0.0;
131-
}
132-
TGeoMaterial *material = startnode->GetVolume()->GetMedium()->GetMaterial();
133-
lparam[0] = material->GetDensity();
134-
if (lparam[0] > mparam[7]) mparam[7]=lparam[0];
135-
lparam[1] = material->GetRadLen();
136-
lparam[2] = material->GetA();
137-
lparam[3] = material->GetZ();
138-
lparam[4] = length;
139-
lparam[5] = lparam[3]/lparam[2];
140-
lparam[6] = material->GetIntLen();
141-
Double_t n = lparam[0]/lparam[2];
142-
Double_t sigma = 1./(n*lparam[6])/mbarn;
143-
if (sigma > mparam[9]) mparam[9]=sigma;
144-
if (material->IsMixture()) {
145-
TGeoMixture * mixture = dynamic_cast<TGeoMixture*>(material);
146-
lparam[5] =0;
147-
Double_t sum =0;
148-
for (Int_t iel=0;iel<mixture->GetNelements();iel++){
149-
sum += mixture->GetWmixt()[iel];
150-
lparam[5]+= mixture->GetZmixt()[iel]*mixture->GetWmixt()[iel]/mixture->GetAmixt()[iel];
151-
}
152-
lparam[5]/=sum;
153-
}
154-
155-
// Locate next boundary within length without computing safety.
156-
// Propagate either with length (if no boundary found) or just cross boundary
157-
gGeoManager->FindNextBoundaryAndStep(length, kFALSE);
158-
Double_t step = 0.0; // Step made
159-
Double_t snext = gGeoManager->GetStep();
160-
// If no boundary within proposed length, return current density
161-
if (!gGeoManager->IsOnBoundary()) {
162-
mparam[0] = lparam[0];
163-
mparam[1] = lparam[4]/lparam[1];
164-
mparam[2] = lparam[2];
165-
mparam[3] = lparam[3];
166-
mparam[4] = lparam[4];
167-
mparam[8] = lparam[4]/lparam[6];
168-
return lparam[0];
169-
}
170-
// Try to cross the boundary and see what is next
171-
Int_t nzero = 0;
172-
while (length>TGeoShape::Tolerance()) {
173-
currentnode = gGeoManager->GetCurrentNode();
174-
if (snext<2.*TGeoShape::Tolerance()) nzero++;
175-
else nzero = 0;
176-
if (nzero>3) {
177-
// This means navigation has problems on one boundary
178-
// Try to cross by making a small step
179-
//AliErrorClass("Cannot cross boundary\n");
180-
mparam[0] = bparam[0]/step;
181-
mparam[1] = bparam[1];
182-
mparam[2] = bparam[2]/step;
183-
mparam[3] = bparam[3]/step;
184-
mparam[5] = bparam[5]/step;
185-
mparam[8] = bparam[6];
186-
mparam[4] = step;
187-
mparam[0] = 0.; // if crash of navigation take mean density 0
188-
mparam[1] = 1000000; // and infinite rad length
189-
return bparam[0]/step;
190-
}
191-
mparam[6]+=1.;
192-
step += snext;
193-
bparam[1] += snext/lparam[1];
194-
bparam[2] += snext*lparam[2];
195-
bparam[3] += snext*lparam[3];
196-
bparam[5] += snext*lparam[5];
197-
bparam[6] += snext/lparam[6];
198-
bparam[0] += snext*lparam[0];
199-
200-
if (snext>=length) break;
201-
if (!currentnode) break;
202-
length -= snext;
203-
material = currentnode->GetVolume()->GetMedium()->GetMaterial();
204-
lparam[0] = material->GetDensity();
205-
if (lparam[0] > mparam[7]) mparam[7]=lparam[0];
206-
lparam[1] = material->GetRadLen();
207-
lparam[2] = material->GetA();
208-
lparam[3] = material->GetZ();
209-
lparam[5] = lparam[3]/lparam[2];
210-
lparam[6] = material->GetIntLen();
211-
n = lparam[0]/lparam[2];
212-
sigma = 1./(n*lparam[6])/mbarn;
213-
if (sigma > mparam[9]) mparam[9]=sigma;
214-
if (material->IsMixture()) {
215-
TGeoMixture * mixture = dynamic_cast<TGeoMixture*>(material);
216-
lparam[5]=0;
217-
Double_t sum =0;
218-
for (Int_t iel=0;iel<mixture->GetNelements();iel++){
219-
sum+= mixture->GetWmixt()[iel];
220-
lparam[5]+= mixture->GetZmixt()[iel]*mixture->GetWmixt()[iel]/mixture->GetAmixt()[iel];
221-
}
222-
lparam[5]/=sum;
223-
}
224-
gGeoManager->FindNextBoundaryAndStep(length, kFALSE);
225-
snext = gGeoManager->GetStep();
226-
}
227-
mparam[0] = bparam[0]/step;
228-
mparam[1] = bparam[1];
229-
mparam[2] = bparam[2]/step;
230-
mparam[3] = bparam[3]/step;
231-
mparam[5] = bparam[5]/step;
232-
mparam[8] = bparam[6];
233-
return bparam[0]/step;
234-
}
235-
23671
std::vector<double> GenieGenerator::Rotate(Double_t x, Double_t y, Double_t z, Double_t px, Double_t py, Double_t pz)
23772
{
23873
//rotate vector px,py,pz to point at x,y,z at origin.
@@ -412,7 +247,7 @@ Bool_t GenieGenerator::ReadEvent(FairPrimaryGenerator* cpg)
412247
if (fFirst){
413248
Double_t bparam=0.;
414249
Double_t mparam[10];
415-
bparam=MeanMaterialBudget(start, end, mparam);
250+
bparam=shipgen::MeanMaterialBudget(start, end, mparam);
416251
cout << "Info GenieGenerator: MaterialBudget " << start[2] << " - "<< end[2] << endl;
417252
cout << "Info GenieGenerator: MaterialBudget " << bparam << endl;
418253
cout << "Info GenieGenerator: MaterialBudget 0 " << mparam[0] << endl;
@@ -511,7 +346,7 @@ Bool_t GenieGenerator::ReadEvent(FairPrimaryGenerator* cpg)
511346
end[1]=tynu*(end[2]-ztarget);
512347
//cout << "Info GenieGenerator: neutrino xyz-end " << end[0] << "-" << end[1] << "-" << end[2] << endl;
513348
//get material density between these two points
514-
bparam=MeanMaterialBudget(start, end, mparam);
349+
bparam=shipgen::MeanMaterialBudget(start, end, mparam);
515350
//printf("param %e %e %e \n",bparam,mparam[6],mparam[7]);
516351
}
517352
}

shipgen/GenieGenerator.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class GenieGenerator : public FairGenerator
3939
endZ = zE;
4040
}
4141
void AddBox(TVector3 dVec, TVector3 box);
42-
Double_t MeanMaterialBudget(const Double_t *start, const Double_t *end, Double_t *mparam);
4342
private:
4443
std::vector<double> Rotate(Double_t x, Double_t y, Double_t z, Double_t px, Double_t py, Double_t pz);
4544

0 commit comments

Comments
 (0)