00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "LCD_DocGeoUtil.hh"
00010 #include "LCD_DocumentUtil.hh"
00011 #include "LCD_DocManager.hh"
00012 #include "LCD_Document.hh"
00013
00014 XERCES_CPP_NAMESPACE_USE
00015
00016
00017 static double getTotalThickness(DOM_Element shape);
00018
00019
00020
00021
00022
00023
00024
00025 double LCD_DocGeoUtil::getLayerWidth(DOM_Element elt, bool all) {
00026 DOM_Element layering;
00027 if ((elt.getTagName()).equals("layering")) {
00028 layering = elt;
00029 }
00030 else {
00031 layering = LCD_DocumentUtil::firstDesc(elt, "layering");
00032 if (layering == 0) return -1.0;
00033 }
00034 DOM_NodeList list = layering.getElementsByTagName(DOMString("slice"));
00035 int nSlice = list.getLength();
00036 int iSlice;
00037 DOM_Element tmpElt;
00038 double tmpValue;
00039 double width = 0.0;
00040 bool ok;
00041
00042
00043 for (iSlice = 0; iSlice < nSlice; iSlice++) {
00044 DOM_Node node = list.item(iSlice);
00045 tmpElt = (DOM_Element &) node;
00046 ok =
00047 LCD_DocumentUtil::convertValue(tmpElt.getAttribute(DOMString("width")),
00048 &tmpValue);
00049 width += tmpValue;
00050 }
00051 if (!all) return width;
00052
00053
00054 int nLayer;
00055
00056 ok = LCD_DocumentUtil::convertValue(layering.getAttribute("n"), &nLayer);
00057 width *= nLayer;
00058
00059 return width;
00060 }
00061
00062
00063
00064
00065 bool LCD_DocGeoUtil::reflected(const DOM_Element& vol)
00066 {
00067 bool refl;
00068
00069
00070 if (!(vol.getTagName().equals("volume"))) return false;
00071
00072
00073
00074 DOM_Element shape = LCD_DocumentUtil::firstDesc(vol, "*");
00075
00076
00077 DOMString reflValue = shape.getAttribute("reflected");
00078
00079 if (reflValue.equals("")) return false;
00080
00081 bool ok = LCD_DocumentUtil::convertValue(reflValue, &refl);
00082 if (ok) return refl;
00083 else return false;
00084
00085
00086
00087
00088
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098 bool LCD_DocGeoUtil::barrelDim(const DOM_Element& tube, double * pInnerR,
00099 double * pOuterZ, double * pOuterR) {
00100 bool ok;
00101
00102 if (!(tube.getTagName().equals("tube"))) return false;
00103
00104 DOM_Element dim;
00105
00106
00107
00108
00109
00110
00111 DOM_Element elt = LCD_DocumentUtil::firstDesc(tube, "*");
00112
00113 if ((elt.getTagName().equals("neighbor"))) {
00114 DOMString neighborId = elt.getAttribute("adjoins");
00115 double gap;
00116 double neighInnerR, neighOuterR;
00117
00118 ok = LCD_DocumentUtil::convertValue(elt.getAttribute("gap"), &gap);
00119
00120
00121
00122 DOM_Document domDoc = elt.getOwnerDocument();
00123
00124
00125 elt = (LCD_DocManager::getLCDDoc(domDoc))->getElement(neighborId,
00126 DOMString("volume"));
00127
00128
00129 elt = LCD_DocumentUtil::firstDesc(elt, "tube");
00130
00131
00132
00133 tubeDim(elt, &neighInnerR, pOuterZ, &neighOuterR);
00134
00135 *pInnerR = neighOuterR + gap;
00136 }
00137
00138 else if ((elt.getTagName().equals("barrel_dimensions"))) {
00139 dim = elt;
00140 ok =
00141 LCD_DocumentUtil::convertValue(dim.getAttribute(DOMString("inner_r")),
00142 pInnerR);
00143
00144 if (ok)
00145 ok =
00146 LCD_DocumentUtil::convertValue(dim.getAttribute(DOMString("outer_z")),
00147 pOuterZ);
00148 }
00149 else return false;
00150
00151 if (pOuterR) *pOuterR = *pInnerR + getTotalThickness(tube);
00152 return ok;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161 bool LCD_DocGeoUtil::tubeDim(const DOM_Element& tube, double *pInnerR,
00162 double *pOffsetZ, double *pLength,
00163 double *pOuterR) {
00164
00165 bool ok;
00166 if (!(tube.getTagName().equals("tube"))) return false;
00167
00168 DOM_Element dim = LCD_DocumentUtil::firstDesc(tube, "*");
00169
00170 if (((dim.getTagName().equals("barrel_dimensions") ) ) ||
00171 ((dim.getTagName().equals("neighbor") ) ) ) {
00172 double outerZ;
00173
00174 ok = barrelDim(tube, pInnerR, &outerZ, pOuterR);
00175
00176 if (ok) {
00177 *pOffsetZ = 0.0;
00178 *pLength = 2 * outerZ;
00179 }
00180 return ok;
00181 }
00182 else if (dim.getTagName().equals("tube_dimensions")) {
00183 ok =
00184 LCD_DocumentUtil::convertValue(dim.getAttribute(DOMString("inner_r")),
00185 pInnerR);
00186 if (ok)
00187 ok =
00188 LCD_DocumentUtil::convertValue(dim.getAttribute(DOMString("offset_z")),
00189 pOffsetZ);
00190 if (ok)
00191 ok =
00192 LCD_DocumentUtil::convertValue(dim.getAttribute(DOMString("length")),
00193 pLength);
00194 if (!pOuterR) return ok;
00195 if (!ok) return false;
00196 else *pOuterR = *pInnerR + getTotalThickness(tube);
00197
00198 return true;
00199 }
00200 return false;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210 bool LCD_DocGeoUtil::diskDim(const DOM_Element& disk, double *pInnerR,
00211 double *pInnerZ, double *pOuterR,
00212 double *pOuterZ) {
00213 bool ok;
00214
00215 if (!(disk.getTagName().equals("disk"))) return false;
00216
00217 DOM_Element dim;
00218
00219
00220
00221
00222 DOM_Element elt = LCD_DocumentUtil::firstDesc(disk, "*");
00223
00224 if ((elt.getTagName().equals("neighbor"))) {
00225 DOMString neighborId = elt.getAttribute("adjoins");
00226 double gap;
00227 double neighOuterZ;
00228
00229 ok = LCD_DocumentUtil::convertValue(elt.getAttribute("gap"), &gap);
00230
00231
00232
00233
00234
00235 DOM_Document domDoc = elt.getOwnerDocument();
00236
00237
00238 elt = (LCD_DocManager::getLCDDoc(domDoc))->getElement(neighborId,
00239 DOMString("volume"));
00240
00241
00242 elt = LCD_DocumentUtil::firstDesc(elt, "*");
00243
00244 if ((elt.getTagName()).equals("tube")) {
00245 barrelDim(elt, pInnerR, &neighOuterZ, pOuterR);
00246 }
00247 else if ((elt.getTagName()).equals("disk")) {
00248 double tmp;
00249 diskDim(elt, pInnerR, &tmp, pOuterR, &neighOuterZ);
00250 }
00251
00252 *pInnerZ = neighOuterZ + gap;
00253 }
00254
00255 else {
00256 ok =
00257 LCD_DocumentUtil::convertValue(elt.getAttribute(DOMString("inner_r")),
00258 pInnerR);
00259
00260 if (ok)
00261 ok =
00262 LCD_DocumentUtil::convertValue(elt.getAttribute(DOMString("inner_z")),
00263 pInnerZ);
00264
00265 if (ok)
00266 ok =
00267 LCD_DocumentUtil::convertValue(elt.getAttribute(DOMString("outer_r")),
00268 pOuterR);
00269 }
00270
00271 if (pOuterZ) *pOuterZ = *pInnerZ + getTotalThickness(disk);
00272
00273 return ok;
00274 }
00275
00276
00277
00278 static double getTotalThickness(DOM_Element shape) {
00279 double tmpValue;
00280 DOM_NodeList list = shape.getElementsByTagName(DOMString("slice"));
00281 DOM_Element tmpElt;
00282 double width;
00283 bool ok;
00284
00285
00286 tmpElt = LCD_DocumentUtil::firstDesc(shape, "layering");
00287 width = LCD_DocGeoUtil::getLayerWidth(tmpElt, true);
00288
00289
00290 tmpElt = LCD_DocumentUtil::firstDesc(shape, DOMString("iwall"));
00291 if (tmpElt != DOM_Element()) {
00292 ok = LCD_DocumentUtil::convertValue(tmpElt.getAttribute("width"),
00293 &tmpValue);
00294 width += tmpValue;
00295 }
00296
00297
00298 tmpElt = LCD_DocumentUtil::firstDesc(shape, "owall");
00299 if (tmpElt != DOM_Element()) {
00300 ok = LCD_DocumentUtil::convertValue(tmpElt.getAttribute("width"),
00301 &tmpValue);
00302 width += tmpValue;
00303 }
00304 return width;
00305 }
00306
00307
00308
00309
00310 bool LCD_DocGeoUtil::coneDim(const DOM_Element& cone,
00311 double *pMinInnerR, double *pMinOuterR,
00312 double *pMaxInnerR, double *pMaxOuterR,
00313 double *pInnerZ, double *pOuterZ) {
00314
00315 double innerWidth, outerWidth;
00316
00317 if (!(cone.getTagName().equals("cone"))) return false;
00318
00319 DOM_Element child = LCD_DocumentUtil::firstDesc(cone, "cone_dimensions");
00320
00321 if (!LCD_DocumentUtil::convertValue(child.getAttribute("min_inner_r"),
00322 pMinInnerR)) return false;
00323 if (!LCD_DocumentUtil::convertValue(child.getAttribute("max_inner_r"),
00324 pMaxInnerR)) return false;
00325 if (!LCD_DocumentUtil::convertValue(child.getAttribute("inner_z"),
00326 pInnerZ)) return false;
00327 if (!LCD_DocumentUtil::convertValue(child.getAttribute("outer_z"),
00328 pOuterZ)) return false;
00329
00330 child = LCD_DocumentUtil::firstDesc(cone, "cone_slice");
00331 if (!LCD_DocumentUtil::convertValue(child.getAttribute("inner_width"),
00332 &innerWidth)) return false;
00333 if (child.getAttributeNode("outer_width") == 0) {
00334 outerWidth = innerWidth;
00335 }
00336 else {
00337 if (!LCD_DocumentUtil::convertValue(child.getAttribute("outer_width"),
00338 &outerWidth)) return false;
00339 }
00340
00341 *pMinOuterR = *pMinInnerR + innerWidth;
00342 *pMaxOuterR = *pMaxInnerR + outerWidth;
00343 return true;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352 double LCD_DocGeoUtil::getLayer0Dist(const DOM_Element& layered) {
00353 bool ok;
00354 double innerBound;
00355
00356 if ((layered.getTagName()).equals("tube")) {
00357 double offsetZ, length;
00358 ok = tubeDim(layered, &innerBound, &offsetZ, &length);
00359 }
00360 else if ((layered.getTagName()).equals("disk")) {
00361 double innerR, outerR;
00362 ok = diskDim(layered, &innerR, &innerBound, &outerR);
00363 }
00364 else return 0.0;
00365 if (!ok) return 0.0;
00366
00367 DOM_Element child = LCD_DocumentUtil::firstDesc(layered, "iwall");
00368 if (child == 0) return innerBound;
00369
00370 double width;
00371
00372 ok =
00373 LCD_DocumentUtil::convertValue(child.getAttribute(DOMString("width")),
00374 &width);
00375 if (ok) innerBound += width;
00376 return innerBound;
00377 }
00378
00379
00380
00381
00382
00383 bool LCD_DocGeoUtil::getSegmentation(const DOM_Element& elt, double *nTheta,
00384 double *nPhi)
00385 {
00386 bool ok;
00387
00388 DOM_Element seg;
00389 if ((elt.getTagName()).equals("segmentation")) {
00390 seg = elt;
00391 }
00392 else {
00393 seg = LCD_DocumentUtil::firstDesc(elt, "segmentation");
00394 if (seg == 0) return false;
00395 }
00396
00397
00398 ok =
00399 LCD_DocumentUtil::convertValue(seg.getAttribute(DOMString("theta")),
00400 nTheta);
00401 if (!ok) ok =
00402 LCD_DocumentUtil::convertValue(seg.getAttribute(DOMString("cos_theta")),
00403 nTheta);
00404
00405 ok = ok &&
00406 LCD_DocumentUtil::convertValue(seg.getAttribute(DOMString("phi")),
00407 nPhi);
00408 return ok;
00409 }