#include "TVector3.h"
#include "hades.h"
#include "hmdclayergeompar.h"
#include "hmdcsizescells.h"
#include "hruntimedb.h"
#include "hkaldef.h"
#include "hkaldetcradle.h"
#include "hkalgeomtools.h"
#include "hkalmdcmeaslayer.h"
#include "hmaterials.h"
#include "hkalmixture.h"
ClassImp(HKalDetCradle)
HKalDetCradle::HKalDetCradle() {
matsMdc = NULL;
matAir = NULL;
nLayersInMdc = 1;
}
HKalDetCradle::HKalDetCradle(Int_t nLayInMdc, const TObjArray *customMats) :
TObjArray(kNumSecs*kNumMdcs*nLayInMdc) {
matsMdc = new HKalMixture*[kNumMdcs];
matAir = NULL;
nLayersInMdc = nLayInMdc;
if(customMats) {
if(customMats->GetEntries() == kNumMdcs+1) {
for(Int_t iMod = 0; iMod < kNumMdcs; iMod++) {
HKalMixture *mat = dynamic_cast<HKalMixture*>(customMats->At(iMod));
if(mat) {
matsMdc[iMod] = mat;
} else {
Error("HKalDetCradle()",
Form("No material found for MDC %i", iMod));
}
}
HKalMixture *mat = dynamic_cast<HKalMixture*>(customMats->At(kNumMdcs));
if(mat) {
matAir = mat;
} else {
Error("HKalDetCradle()",
Form("No object found at index %i", kNumMdcs));
}
} else {
Error("HKalDetCradle()",
Form("Size of materials array is %i. Expected %i.",
customMats->GetEntries(), kNumMdcs));
}
} else {
initMdcMaterials();
}
for(Int_t iSec = 0; iSec < kNumSecs; iSec++) {
for(Int_t iMod = 0; iMod < kNumMdcs; iMod++) {
#if kalDebug > 0
if(!HMdcSizesCells::getObject()) {
Warning("HKalDetCradle(Int_t)", "HMdcSizesCells has not been initialized. Measurement layers not added to detector cradle.");
break;
}
#endif
addMdcLayersToCradle(HMdcSizesCells::getObject(), iSec, iMod, nLayersInMdc);
}
}
}
HKalDetCradle::~HKalDetCradle() {
delete [] matsMdc;
delete matAir;
}
void HKalDetCradle::addMdcLayersToCradle(const HMdcSizesCells *fSizesCells,
Int_t sector, Int_t module, Int_t nLayers) {
HRuntimeDb *rtdb = gHades->getRuntimeDb();
HMdcLayerGeomPar *layerGeomPar = (HMdcLayerGeomPar*)rtdb->getContainer("MdcLayerGeomPar");
for (Int_t layer = 0; layer < nLayers; layer++) {
#if kalDebug > 0
if(!secOk(sector)) {
Error("addMdcLayersToCradle()", Form("Invalid sector number: %i. Layers not added to cradle.", sector));
break;
}
if(!modOk(module)) {
Error("addMdcLayersToCradle()", Form("Invalid module number: %i. Layers not added to cradle.", module));
break;
}
if(!fSizesCells) {
Error("addMdcLayersToCradle()", "HMdcSizesCells is not initialized.");
}
#endif
Double_t x = 0.;
Double_t y = 0.;
Double_t z = 0.;
if(nLayers == 1) {
HKalGeomTools::TransModuleToSector(x, y, z, sector, module);
} else {
HKalGeomTools::TransLayerToSector(x, y, z, sector, module, layer);
}
TVector3 vPlaneCenter(x, y, z);
x = 0.;
y = 0.;
z = 1.;
if(nLayers == 1) {
HKalGeomTools::TransModuleToSector(x, y, z, sector, module);
} else {
HKalGeomTools::TransLayerToSector(x, y, z, sector, module, layer);
}
TVector3 vZ(x, y, z);
TVector3 vPlaneNormal = vZ - vPlaneCenter;
vPlaneNormal.Unit();
if(vPlaneCenter * vPlaneNormal < 0) {
vPlaneNormal *= -1.;
}
HKalMdcMeasLayer *meas;
HMdcLayerGeomParLay &layerGeomParLay = (HMdcLayerGeomParLay&)(*layerGeomPar)[sector][module][layer];
Double_t layerThickness = layerGeomParLay.getCatDist();
if(nLayers == 1) {
layerThickness *= 8.;
}
if(nLayers != 1 && layer == 0) {
meas = new HKalMdcMeasLayer(vPlaneCenter, vPlaneNormal, matsMdc[module], matAir,
module, sector, layer, nLayersInMdc, layerThickness);
} else {
meas = new HKalMdcMeasLayer(vPlaneCenter, vPlaneNormal, matsMdc[module], matAir,
module, sector, layer, nLayersInMdc, layerThickness);
}
install(meas);
}
SetOwner();
}
const HKalMdcMeasLayer* HKalDetCradle::getMdcLayerAt(Int_t sector, Int_t module, Int_t layer) const {
Int_t layIdx = (sector*kNumMdcs + module)*nLayersInMdc;
if(layer != 6) {
layIdx += layer;
}
#ifdef kalDebug
if(layIdx < 0 || layIdx > GetEntries() - 1) {
Error("getMdcLayerAt()", Form("Mdc layer at sector %i, module %i, layer %i not found in detector cradle. Tried to access element at index %i.", sector, module, layer, layIdx));
exit(1);
}
if(!At(layIdx)->InheritsFrom("HKalMdcMeasLayer")) {
Error("getMdcLayerAt()", Form("Object at index %i in detector cradle is of class %s. Expected class HKalMdcMeasLayer.", layIdx, At(layIdx)->ClassName()));
exit(1);
}
return (HKalMdcMeasLayer*)At(layIdx);
#else
return (HKalMdcMeasLayer*)At(layIdx);
#endif
}
HKalMixture* HKalDetCradle::getMdcMaterial(mdcComponent comp, Int_t module) const {
if(!modOk(module)) {
Error("getMdcMaterial()", Form("%i is not a valid module number", module));
return NULL;
}
HKalMixture *mdcMix = NULL;
Float_t mat[kNumMdcMats];
switch(comp) {
case kCatWi:
case kFieldWi:
mdcMix = new HKalMixture("Aluminum", "altu", 1);
getProperties(mat, "al");
mdcMix->defineElement(0, mat, 1.F);
mdcMix->calcMixture();
break;
case kSenseWi:
Float_t vol[2], rho[2], w[2];
rho[0] = HMaterials::getDensity("Copper");
rho[1] = HMaterials::getDensity("Beryllium");
vol[0] = .98;
vol[1] = .02;
mdcMix = new HKalMixture("Copper/Beryllium 98/2", "co/be", 2);
mdcMix->calcMassFracFromVolFrac(w, 2, rho, vol);
getProperties(mat, "Copper");
mdcMix->defineElement(0, mat, w[0]);
getProperties(mat, "Beryllium");
mdcMix->defineElement(1, mat, w[1]);
mdcMix->calcMixture();
break;
case kWindow:
mdcMix = new HKalMixture("Mylar", "mylar", 1);
getProperties(mat, "mylar");
mdcMix->defineElement(0, mat, 1.F);
mdcMix->calcMixture();
break;
case kGas:
if(module == 0) {
Float_t vol[2], rho[2], w[2];
rho[0] = HMaterials::getDensity("argon");
rho[1] = HMaterials::getDensity("CO2");
vol[0] = .70;
vol[1] = .30;
mdcMix = new HKalMixture("Argon-Isobutane 70:30", "arco2_70_30", 2);
mdcMix->calcMassFracFromVolFrac(w, 2, rho, vol);
getProperties(mat, "argon");
mdcMix->defineElement(0, mat, w[0]);
getProperties(mat, "CO2");
mdcMix->defineElement(1, mat, w[1]);
mdcMix->calcMixture();
} else {
Float_t vol[2], rho[2], w[2];
rho[0] = HMaterials::getDensity("helium");
rho[1] = HMaterials::getDensity("butane");
vol[0] = .84;
vol[1] = .16;
mdcMix = new HKalMixture("Helium-Isobutane 60:40", "hebutane", 2);
mdcMix->calcMassFracFromVolFrac(w, 2, rho, vol);
getProperties(mat, "helium");
mdcMix->defineElement(0, mat, w[0]);
getProperties(mat, "butane");
mdcMix->defineElement(1, mat, w[1]);
mdcMix->calcMixture();
}
break;
}
return mdcMix;
}
void HKalDetCradle::getMdcMaterialVolumeFracs(Float_t volFracs[kNumMdcMats],
Int_t sector, Int_t module, Int_t layer) const {
if(!layOk(layer)) {
Error("getMdcMaterialVolumeFracs()", Form("%i is not a valid layer number", layer));
return;
}
if(!modOk(module)) {
Error("getMdcMaterialVolumeFracs()", Form("%i is not a valid module number", module));
return;
}
HRuntimeDb *rtdb = gHades->getRuntimeDb();
HMdcLayerGeomPar *layerGeomPar = (HMdcLayerGeomPar*)rtdb->getContainer("MdcLayerGeomPar");
HMdcLayerGeomParLay &layerGeomParLay = (HMdcLayerGeomParLay&)(*layerGeomPar)[sector][module][layer];
Float_t nLayers = 6;
Float_t xCell = layerGeomParLay.getCatDist();
Float_t xMylar = .012;
Float_t pitchCatWi;
if(module == 3) {
pitchCatWi = 4.F;
} else {
pitchCatWi = 2.F;
}
Float_t pitchFieldWi = xCell;
Float_t pitchSenseWi = xCell;
Double_t pi = TMath::Pi();
Float_t rCatWi = layerGeomParLay.getCathodeWireThickness() / 2;
Float_t rFieldWi;
if(module == 0 || module == 1) {
rFieldWi = 0.04;
} else {
rFieldWi = 0.05;
}
Float_t rSenseWi;
if(module == 3) {
rSenseWi = 0.015;
} else {
rSenseWi = 0.01;
}
Float_t thicknessCell[kNumMdcMats];
thicknessCell[kCatWi] = pi * rCatWi * rCatWi / pitchCatWi;
thicknessCell[kFieldWi] = pi * rFieldWi * rFieldWi / pitchFieldWi;
thicknessCell[kSenseWi] = pi * rSenseWi * rSenseWi / pitchSenseWi;
thicknessCell[kWindow] = xMylar;
thicknessCell[kGas] = xCell - (thicknessCell[kCatWi] + thicknessCell[kFieldWi] + thicknessCell[kSenseWi]);
Float_t thickness[kNumMdcMats];
thickness[kCatWi] = (nLayers+1) * thicknessCell[kCatWi];
thickness[kFieldWi] = nLayers * thicknessCell[kFieldWi];
thickness[kSenseWi] = nLayers * thicknessCell[kSenseWi];
thickness[kWindow] = 2 * thicknessCell[kWindow];
thickness[kGas] = nLayers * thicknessCell[kGas] + xCell * 2;
Float_t thicknessTotal = 0.F;
for(Int_t i = 0; i < kNumMdcMats; i++) {
thicknessTotal += thickness[i];
}
for(Int_t i = 0; i < kNumMdcMats; i++) {
volFracs[i] = thickness[i] / thicknessTotal;
}
}
void HKalDetCradle::initMdcMaterials() {
Float_t mat[5];
matAir = new HKalMixture("Air", "air", 1);
getProperties(mat, "air");
matAir->defineElement(0, mat, 1.F);
matAir->calcMixture();
HKalMixture const *matsMdcComp [kNumMdcMats];
Float_t rhoMatsMdcComp [kNumMdcMats];
Float_t volFracsMdcComp [kNumMdcMats];
Float_t massFracsMdcComp[kNumMdcMats];
Int_t sector = 0;
Int_t layer = 0;
for(Int_t iModule = 0; iModule < kNumMdcs; iModule++) {
for(Int_t iComp = 0; iComp < kNumMdcMats; iComp++) {
matsMdcComp [iComp] = getMdcMaterial((mdcComponent)iComp, iModule);
rhoMatsMdcComp[iComp] = matsMdcComp[iComp]->GetDensity();
}
getMdcMaterialVolumeFracs(volFracsMdcComp, sector, iModule, layer);
HKalMixture::calcMassFracFromVolFrac(massFracsMdcComp, kNumMdcMats, rhoMatsMdcComp, volFracsMdcComp);
matsMdc[iModule] = new HKalMixture(Form("Materials for mdc plane %i.", iModule), "mdc", kNumMdcMats);
for(Int_t iComp = 0; iComp < kNumMdcMats; iComp++) {
matsMdc[iModule]->defineElement(iComp, matsMdcComp[iComp]->GetA(), matsMdcComp[iComp]->GetZ(),
matsMdcComp[iComp]->GetDensity(), matsMdcComp[iComp]->GetExciteEner(),
matsMdcComp[iComp]->GetRadLength(), massFracsMdcComp[iComp]);
}
matsMdc[iModule]->calcMixture();
for(Int_t iComp = 0; iComp < kNumMdcMats; iComp++) {
delete matsMdcComp[iComp];
}
}
}
void HKalDetCradle::getProperties(Float_t mat[5], const Char_t *id) {
mat[Kalman::kMatIdxA] = HMaterials::getA(id);
mat[Kalman::kMatIdxZ] = HMaterials::getZ(id);
mat[Kalman::kMatIdxDensity] = HMaterials::getDensity(id);
mat[Kalman::kMatIdxExEner] = HMaterials::getExciteEner(id);
mat[Kalman::kMatIdxRadLength] = HMaterials::getRadLength(id);
Float_t corrRho = 1.e-3;
Float_t corrI = 1.e-6;
Float_t corrX0 = 10.F;
mat[Kalman::kMatIdxDensity] *= corrRho;
mat[Kalman::kMatIdxExEner] *= corrI;
mat[Kalman::kMatIdxRadLength] *= corrX0;
}
void HKalDetCradle::install(HKalMdcMeasLayer *layer) {
Add(layer);
}