00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "gismo/TowerArray.h"
00010
00011 #include "gismo/MCParticle.h"
00012 #include "geometry/Box.h"
00013 #include "geometry/CoordTransform.h"
00014 #include "geomrep/BoxRep.h"
00015 #include "Random.h"
00016 #include <algorithm>
00017 float
00018 TowerArray::s_display_scale=10.;
00019
00020 void
00021 TowerArray::score(MCParticle* track)
00022 {
00023 float deltaE = track->energyLoss();
00024 if( deltaE<=0 || track->mass()==0 && track->status()==MCParticle::ALIVE)
00025 return;
00026 Point pos(track->position());
00027 pos.transform(globalToLocal());
00028 long i = calculateIndex(pos);
00029 if(i < 0) return;
00030
00031 scoreTower(i, deltaE);
00032 return;
00033 }
00034
00035 float
00036 TowerArray::scoreTower(long ix, float deltaE)
00037 {
00038 bool found=false;
00039 float etot = deltaE;
00040
00041 for( iterator tower = begin(); tower != end(); ++tower) {
00042 TowerElement& s = *tower;
00043 if( ix > s.index()) continue;
00044 if( ix == s.index() ) {
00045 etot = (s += deltaE);
00046 }
00047 else {
00048
00049 insert(tower, TowerElement( ix, deltaE) );
00050 }
00051 found = true;
00052 break;
00053 }
00054
00055
00056
00057 if( !found ) {
00058 push_back(TowerElement( ix, deltaE) );
00059 }
00060 return etot;
00061
00062 }
00063
00064 long
00065 TowerArray::calculateIndex(const Point& point) const
00066 {
00067 int ix = (int)((point.x()/xWidth+0.5)*xSegmentation);
00068 int iy = (int)((point.y()/yWidth+0.5)*ySegmentation);
00069
00070 ix = std::min(xSegmentation-1,std::max(ix,0));
00071 iy = std::min(ySegmentation-1,std::max(iy,0));
00072
00073
00074
00075
00076 return ix*ySegmentation + iy;
00077
00078
00079 }
00080 void
00081 TowerArray::calculateBin(long ind, float& xmin, float& ymin) const
00082 {
00083
00084 float fy = ind%ySegmentation;
00085 float fx = ind/ySegmentation;
00086 xmin = (fx/xSegmentation-0.5)*xWidth + xWidth/xSegmentation/2.;
00087 ymin = (fy/ySegmentation-0.5)*yWidth + yWidth/ySegmentation/2.;
00088
00089 }
00090 int TowerArray::hits()const
00091 { return (int)size();}
00092
00093 float TowerArray::energy(unsigned i)const
00094 { return towers(i)->energy();
00095 }
00096
00097 Point
00098 TowerArray::xtalPos(unsigned i)const
00099 {
00100 float xmin, ymin;
00101 calculateBin(towers(i)->index(), xmin, ymin);
00102
00103 Point center(xmin
00104 ,ymin
00105 ,0);
00106 center.transform(localToGlobal());
00107 return center;
00108 }
00109
00110 long TowerArray::xtalId(unsigned i)const
00111 { return towers(i)->index(); }
00112
00113 void
00114 TowerArray::clear()
00115 {
00116 TowerElementList::erase(begin(), end());
00117 }
00118
00119 void
00120 TowerArray::generateResponse()
00121 {
00122 for(iterator it = begin(); it != end(); ++it){
00123 TowerElement& theTower = *it;
00124
00125 theTower.simEnergy = theTower.energy();
00126 if(energyResolution > 0)
00127 theTower.simEnergy += Random::gauss() * energyResolution *
00128 sqrt(theTower.energy());
00129 }
00130 }
00131
00132 Point *
00133 TowerArray::meanEnergy(float Ethres, float *Etotal, int *numTowers)
00134 {
00135 float xCenter, yCenter;
00136 float eX = 0.;
00137 float eY = 0.;
00138 *numTowers = 0;
00139
00140 *Etotal = 0.;
00141 for(iterator theTower = begin(); theTower<end(); ++theTower){
00142
00143 if(theTower->simEnergy >= Ethres) {
00144 *Etotal += theTower->simEnergy;
00145 calculateBin(theTower->index(), xCenter, yCenter);
00146 eX += xCenter * theTower->simEnergy;
00147 eY += yCenter * theTower->simEnergy;
00148 *numTowers += 1;
00149 }
00150 }
00151 if(*numTowers > 0) {
00152 eX = eX/(*Etotal);
00153 eY = eY/(*Etotal);
00154 }
00155 Point *retHit = new Point(eX, eY, zPlane);
00156 retHit->transform(localToGlobal());
00157 return retHit;
00158 }
00159
00160 void
00161 TowerArray::draw(gui::DisplayRep& view)const
00162 {
00163 if(size() == 0) return;
00164
00165 const CoordTransform T= localToGlobal();
00166
00167 for(const_iterator t = begin(); t<end(); ++t){
00168 const TowerElement& theTower = *t;
00169 float xmin, ymin;
00170 float height = theTower.energy()* displayScale();
00171 if( height <= 0 ) continue;
00172 calculateBin(theTower.index(), xmin, ymin);
00173 Box box(xWidth/xSegmentation,
00174 yWidth/ySegmentation,
00175 height );
00176
00177 box.move(Vector(xmin,ymin,zPlane+height/2));
00178 box.transform(T);
00179
00180 view.append(BoxRep(box));
00181 }
00182 }
00183
00184 void TowerArray::readData(std::istream& is)
00185 {
00186 clear();
00187 int count;
00188 is >> count;
00189 while (count --)
00190 { unsigned id; int ie;
00191 is >> id >> ie;
00192 push_back(TowerElement(id, ie/1e6));
00193 }
00194
00195 }
00196 void TowerArray::writeData(std::ostream& os)
00197 {
00198 os << size() << '\n';
00199 for(iterator theTower = begin(); theTower<end(); ++theTower){
00200 os << theTower->index() << '\t'<< int(1e6*theTower->energy()) << '\n';
00201
00202 }
00203 }
00204 void TowerArray::printOn(std::ostream& cout)const
00205 {
00206 float total=0, xmin,ymin;
00207 for(const_iterator theTower = begin(); theTower<end(); ++theTower){
00208
00209 calculateBin(theTower->index(),xmin,ymin);
00210 cout << theTower->index() << ' '
00211 << xmin << ' ' << ymin << ' '
00212 << theTower->energy() << '\n';
00213 total += theTower->energy();
00214 }
00215 cout << "total: " << total << '\n';
00216 }
00217
00218
00219
00220 void TowerArray::writeParameters(std::ostream& out) const{
00221 out << xSegmentation <<'\t'
00222 << ySegmentation <<'\t'
00223 << xWidth <<'\t'
00224 << yWidth <<'\t'
00225 << zPlane <<'\t';
00226 }
00227
00228
00229 TowerArray::~TowerArray()
00230 {
00231 clear();
00232 }
00233
00234
00235 TowerElement::~TowerElement()
00236 {
00237 }
00238