File indexing completed on 2025-01-30 09:18:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <TError.h>
0027 #include <TFile.h>
0028 #include <TH2F.h>
0029
0030
0031 #include <DD4hep/Detector.h>
0032 #include <DD4hep/Printout.h>
0033 #include <DDRec/MaterialManager.h>
0034
0035 #include <iostream>
0036 #include <climits>
0037 #include <cerrno>
0038 #include <string>
0039 #include <map>
0040
0041 #undef NDEBUG
0042 #include <cassert>
0043
0044 using namespace dd4hep;
0045 using namespace dd4hep::rec;
0046
0047 using std::cout;
0048 using std::endl;
0049
0050 int main_wrapper(int argc, char** argv) {
0051 struct Handler {
0052 Handler() { SetErrorHandler(Handler::print); }
0053 static void print(int level, Bool_t abort, const char *location, const char *msg) {
0054 if ( level > kInfo || abort ) ::printf("%s: %s\n", location, msg);
0055 }
0056 static void usage() {
0057 std::cout << " usage: graphicalScan compact.xml axis xMin xMax yMin yMax zMin zMax nSlices nBins nSamples FieldOrMaterial OutfileName" << std::endl
0058 << " axis (X, Y, or Z) : perpendicular to the slices" << std::endl
0059 << " xMin xMax yMin yMax zMin zMax : range of scans " << std::endl
0060 << " nSlices : number of slices (equally spaced along chose axis)" << std::endl
0061 << " nBins : number of bins along each axis of histograms" << std::endl
0062 << " nSamples : the number of times each bin is sampled " << std::endl
0063 << " FieldOrMaterial : scan field or material? F = field, M = material, FM or MF = both" << std::endl
0064 << " OutfileName : output root file name" << std::endl
0065 << " -> produces graphical scans of material and/or fields defined in a compact xml description"
0066 << std::endl;
0067 exit(1);
0068 }
0069 } _handler;
0070
0071
0072
0073
0074
0075 if( argc != 14 ) Handler::usage();
0076
0077 std::string inFile = argv[1];
0078
0079 std::string XYZ = argv[2];
0080
0081 TString labx, laby;
0082 unsigned int index[3] = {99,99,99};
0083 if ( XYZ=="x" || XYZ=="X" ) {
0084 index[0] = 0;
0085 index[1] = 2;
0086 index[2] = 1;
0087 labx="Z [cm]";
0088 laby="Y [cm]";
0089 } else if ( XYZ=="y" || XYZ=="Y" ) {
0090 index[0] = 1;
0091 index[1] = 2;
0092 index[2] = 0;
0093 labx="Z [cm]";
0094 laby="X [cm]";
0095 } else if ( XYZ=="z" || XYZ=="Z" ) {
0096 index[0] = 2;
0097 index[1] = 0;
0098 index[2] = 1;
0099 labx="X [cm]";
0100 laby="Y [cm]";
0101 } else {
0102 cout << "invalid XYZ" << endl;
0103 return -1;
0104 }
0105
0106 double x0,y0,z0,x1,y1,z1;
0107 unsigned int nslice, nbins, mm_count;
0108 std::stringstream sstr;
0109 sstr <<
0110 argv[3] << " " << argv[4] << " " << argv[5] << " " <<
0111 argv[6] << " " << argv[7] << " " << argv[8] << " " <<
0112 argv[9] << " " << argv[10] << " " << argv[11] << "NONE";
0113 sstr >> x0 >> x1 >> y0 >> y1 >> z0 >> z1 >> nslice >> nbins >> mm_count ;
0114 if ( !sstr.good() ) {
0115 Handler::usage();
0116 ::exit(EINVAL);
0117 }
0118
0119 std::string FM = argv[12];
0120 std::string outFileName = argv[13];
0121
0122 if ( x0>x1 ) { double temp=x0; x0=x1; x1=temp; }
0123 if ( y0>y1 ) { double temp=y0; y0=y1; y1=temp; }
0124 if ( z0>z1 ) { double temp=z0; z0=z1; z1=temp; }
0125
0126 if ( ! (nbins>0 && nbins<USHRT_MAX && nslice>0 && nslice<USHRT_MAX) ) {
0127 cout << "funny # bins/slices " << endl;
0128 ::exit(EINVAL);
0129 }
0130
0131 bool scanField(false);
0132 bool scanMaterial(false);
0133 if ( FM=="f" || FM=="F" ) {
0134 scanField=true;
0135 } else if ( FM=="m" || FM=="M" ) {
0136 scanMaterial=true;
0137 } else if ( FM=="fm" || FM=="FM" || FM=="mf" || FM=="MF" ) {
0138 scanField=true;
0139 scanMaterial=true;
0140 } else {
0141 cout << "invalid field/material flag: use one of f/F/m/M/fm/FM/mf/MF" << endl;
0142 return 1;
0143 }
0144
0145 double mmin[3]={x0,y0,z0};
0146 double mmax[3]={x1,y1,z1};
0147
0148
0149
0150
0151 Detector& description = Detector::getInstance();
0152 description.fromCompact(inFile);
0153
0154
0155
0156 TFile* f = new TFile(outFileName.c_str(),"recreate");
0157
0158 Vector3D p0, p1;
0159
0160 MaterialManager matMgr(description.world().volume() ) ;
0161
0162 for (unsigned int isl=0; isl<nslice; isl++) {
0163
0164 double sz = nslice > 1 ?
0165 mmin[index[0]] + isl*( mmax[index[0]] - mmin[index[0]] )/( nslice - 1 ) :
0166 (mmin[index[0]] + mmax[index[0]])/2. ;
0167
0168 p0.array()[ index[0] ] = sz;
0169 p1.array()[ index[0] ] = sz;
0170
0171 cout << "scanning slice " << isl << " at "+XYZ+" = " << sz << endl;
0172
0173 TString dirn = "Slice"; dirn+=isl;
0174 f->mkdir(dirn);
0175 f->cd(dirn);
0176
0177 std::map < std::string , TH2F* > scanmap;
0178
0179
0180 TString hn = "slice"; hn+=isl; hn+="_X0";
0181 TString hnn = "X0 "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0182
0183 for (int j=1; j<=2; j++) {
0184 if ( mmax[index[j]] - mmin[index[j]] < 1e-4 ) {
0185 cout << "ERROR: max and min of axis are the same!" << endl;
0186 assert(0);
0187 }
0188 }
0189
0190
0191 TH2F* h2slice = 0;
0192
0193 if (scanMaterial) {
0194
0195 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0196 scanmap["x0"] = h2slice;
0197
0198 hn = "slice"; hn+=isl; hn+="_lambda";
0199 hnn = "lambda "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0200 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0201 scanmap["lambda"] = h2slice;
0202 }
0203
0204 if (scanField) {
0205 hn = "slice"; hn+=isl; hn+="_Bx";
0206 hnn = "Bx[T] "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0207 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0208 scanmap["Bx"] = h2slice;
0209
0210 hn = "slice"; hn+=isl; hn+="_By";
0211 hnn = "By[T] "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0212 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0213 scanmap["By"] = h2slice;
0214
0215 hn = "slice"; hn+=isl; hn+="_Bz";
0216 hnn = "Bz[T] "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0217 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0218 scanmap["Bz"] = h2slice;
0219
0220 hn = "slice"; hn+=isl; hn+="_Ex";
0221 hnn = "Ex[V/m] "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0222 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0223 scanmap["Ex"] = h2slice;
0224
0225 hn = "slice"; hn+=isl; hn+="_Ey";
0226 hnn = "Ey[V/m] "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0227 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0228 scanmap["Ey"] = h2slice;
0229
0230 hn = "slice"; hn+=isl; hn+="_Ez";
0231 hnn = "Ez[V/m] "; hnn += XYZ; hnn+="="; hnn += Form("%7.3f",sz); hnn+=" [cm]";
0232 h2slice = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0233 scanmap["Ez"] = h2slice;
0234 }
0235
0236
0237 for (int ix=1; ix<=h2slice->GetNbinsX(); ix++) {
0238
0239 double xmin = h2slice->GetXaxis()->GetBinLowEdge(ix);
0240 double xmax = h2slice->GetXaxis()->GetBinUpEdge(ix);
0241
0242 for (int iy=1; iy<=h2slice->GetNbinsY(); iy++) {
0243
0244 double ymin = h2slice->GetYaxis()->GetBinLowEdge(iy);
0245 double ymax = h2slice->GetYaxis()->GetBinUpEdge(iy);
0246
0247 if (scanField) {
0248
0249 double posV[3];
0250 posV[index[0]] = sz;
0251 posV[index[1]] = 0.5*(xmin+xmax);
0252 posV[index[2]] = 0.5*(ymin+ymax);
0253
0254 double fieldV[3] ;
0255 description.field().combinedMagnetic( posV , fieldV ) ;
0256 scanmap["Bx"]->SetBinContent(ix, iy, fieldV[0] / dd4hep::tesla );
0257 scanmap["By"]->SetBinContent(ix, iy, fieldV[1] / dd4hep::tesla );
0258 scanmap["Bz"]->SetBinContent(ix, iy, fieldV[2] / dd4hep::tesla );
0259
0260 description.field().combinedElectric( posV , fieldV ) ;
0261 scanmap["Ex"]->SetBinContent(ix, iy, fieldV[0] / ( dd4hep::volt/dd4hep::meter ) );
0262 scanmap["Ey"]->SetBinContent(ix, iy, fieldV[1] / ( dd4hep::volt/dd4hep::meter ) );
0263 scanmap["Ez"]->SetBinContent(ix, iy, fieldV[2] / ( dd4hep::volt/dd4hep::meter ) );
0264 }
0265
0266 if (scanMaterial) {
0267
0268
0269 double sum_lambda(0);
0270 double sum_x0(0);
0271 double sum_length(0);
0272
0273 std::map < std::string , float > materialmap;
0274
0275 for (unsigned int jx=0; jx<2*mm_count; jx++) {
0276 if ( jx<mm_count ) {
0277 double xcom = xmin + (1+jx)*( xmax - xmin )/(mm_count+1.);
0278 p0.array()[index[1]] = xcom; p0.array()[index[2]] = ymin;
0279 p1.array()[index[1]] = xcom; p1.array()[index[2]] = ymax;
0280 } else {
0281 double ycom = ymin + (jx-mm_count+1)*( ymax - ymin )/(mm_count+1.);
0282 p0.array()[index[1]] = xmin; p0.array()[index[2]] = ycom;
0283 p1.array()[index[1]] = xmax; p1.array()[index[2]] = ycom;
0284 }
0285
0286 const MaterialVec& materials = matMgr.materialsBetween(p0, p1);
0287 for( unsigned i=0,n=materials.size();i<n;++i){
0288 TGeoMaterial* mat = materials[i].first->GetMaterial();
0289 double length = materials[i].second;
0290 sum_length += length;
0291 double nx0 = length / mat->GetRadLen();
0292 sum_x0 += nx0;
0293 double nLambda = length / mat->GetIntLen();
0294 sum_lambda += nLambda;
0295
0296 std::string mname = mat->GetName();
0297 if ( materialmap.find( mname )!=materialmap.end() ) {
0298 materialmap[mname]+=length;
0299 } else {
0300 materialmap[mname]=length;
0301 }
0302
0303 }
0304
0305 }
0306
0307 scanmap["x0"]->SetBinContent(ix, iy, sum_x0/sum_length);
0308 scanmap["lambda"]->SetBinContent(ix, iy, sum_lambda/sum_length);
0309
0310 for ( std::map < std::string , float >::iterator jj = materialmap.begin(); jj!=materialmap.end(); jj++) {
0311 if ( scanmap.find( jj->first )==scanmap.end() ) {
0312 hn = "slice"; hn+=isl; hn+="_"+jj->first;
0313 hnn = jj->first; hnn += " "+XYZ; hnn+="=";
0314
0315 hnn += Form("%7.3f",sz);
0316 hnn+=" [cm]";
0317 scanmap[jj->first] = new TH2F( hn, hnn, nbins, mmin[index[1]], mmax[index[1]], nbins, mmin[index[2]], mmax[index[2]] );
0318 }
0319 scanmap[jj->first]->SetBinContent(ix, iy, jj->second / sum_length );
0320 }
0321
0322 }
0323
0324 }
0325 }
0326
0327 for ( std::map < std::string , TH2F* >::iterator jj = scanmap.begin(); jj!=scanmap.end(); jj++) {
0328 jj->second->SetOption("zcol");
0329 jj->second->GetXaxis()->SetTitle(labx);
0330 jj->second->GetYaxis()->SetTitle(laby);
0331 }
0332 }
0333 f->Write();
0334 f->Close();
0335 return 0;
0336 }
0337
0338
0339 int main(int argc, char** argv) {
0340 try {
0341 return main_wrapper(argc, argv);
0342 }
0343 catch(const std::exception& e) {
0344 std::cout << "Got uncaught exception: " << e.what() << std::endl;
0345 }
0346 catch (...) {
0347 std::cout << "Got UNKNOWN uncaught exception." << std::endl;
0348 }
0349 return EINVAL;
0350 }