3 /////////////////////////////////////////////////////////////////////////
4 // ITS geometry manipulation routines.
5 // Created April 15 1999.
9 // A package of geometry routines to do transformations between
10 // local, detector active area, and ALICE global coordinate system in such
11 // a way as to allow for detector alignment studies and the like. All of
12 // the information needed to do the coordinate transformation are kept in
13 // a specialized structure for ease of implementation.
14 /////////////////////////////////////////////////////////////////////////
16 #include "TObjArray.h"
17 #include "AliITSgeomSPD.h"
18 #include "AliITSgeomSDD.h"
19 #include "AliITSgeomSSD.h"
21 ////////////////////////////////////////////////////////////////////////
22 // The structure ITS_geom:
23 // The structure ITS_geom has been defined to hold all of the
24 // information necessary to do the coordinate transformations for one
25 // detector between the ALICE Cartesian global and the detector local
26 // coordinate systems. The rotations are implemented in the following
27 // order, Rz*Ry*Rx*(Vglobal-Vtrans)=Vlocal (in matrix notation).
28 // In addition it contains an index to the TObjArray containing all of
29 // the information about the shape of the active detector volume, and
30 // any other useful detector parameters. See the definition of *fShape
31 // below and the classes AliITSgeomSPD, AliITSgeomSDD, and AliITSgeomSSD
32 // for a full description. This structure is not available outside of
36 // The index to the array of detector shape information. In this way
37 // only an index is needed to be stored and not all of the shape
38 // information. This saves much space since most, if not all, of the
39 // detectors of a give type have the same shape information and are only
40 // placed in a different spot in the ALICE/ITS detector.
42 // Float_t fx0,fy0,fz0
43 // The Cartesian translation vector used to define part of the
44 // coordinate transformation. The units of the translation are kept
45 // in the Monte Carlo distance units, usually cm.
47 // Float_t frx,fry,frz
48 // The three rotation angles that define the rotation matrix. The
49 // angles are, frx the rotation about the x axis. fry the rotation about
50 // the "new" or "rotated" y axis. frz the rotation about the "new" or
51 // "rotated" z axis. These angles, although redundant with the rotation
52 // matrix fr, are kept for speed. This allows for their retrieval without
53 // having to compute them each and every time. The angles are kept in
57 // The 3x3 rotation matrix defined by the angles frx, fry, and frz,
58 // for the Global to Local transformation is
59 // |fr[0] fr[1] fr[2]| | cos(frz) sin(frz) 0| | cos(fry) 0 sin(fry)|
60 // fr=|fr[3] fr[4] fr[4]|=|-sin(frz) cos(frz) 0|*| 0 1 0 |
61 // |fr[6] fr[7] fr[8]| | 0 0 1| |-sin(fry) 0 cos(fry)|
64 // *|0 cos(frx) sin(frx)|
65 // |0 -sin(frx) cos(frx)|
67 // Even though this information is redundant with the three rotation
68 // angles, because this transformation matrix can be used so much it is
69 // kept to speed things up a lot. The coordinate system used is Cartesian.
70 ////////////////////////////////////////////////////////////////////////
73 Int_t fShapeIndex; // Shape index for this volume
74 Float_t fx0,fy0,fz0; // Translation vector
75 Float_t frx,fry,frz; // Rotation about axis, angle radians
76 Float_t fr[9]; // the rotation matrix
79 //_______________________________________________________________________
81 class AliITSgeom : public TObject {
82 ////////////////////////////////////////////////////////////////////////
85 // Written by Bjorn S. Nilsen
90 // The number of ITS layers for this geometry. By default this
91 // is 6, but can be modified by the creator function if there are
92 // more layers defined.
95 // A pointer to an array fNlayers long containing the number of
96 // ladders for each layer. This array is typically created and filled
97 // by the AliITSgeom creator function.
100 // A pointer to an array fNlayers long containing the number of
101 // active detector volumes for each ladder. This array is typically
102 // created and filled by the AliITSgeom creator function.
105 // A pointer to an array of pointers pointing to the ITS_geom
106 // structure containing the coordinate transformation information.
107 // The ITS_geom structure corresponding to layer=lay, ladder=lad,
108 // and detector=det is gotten by fg[lay-1][(fNlad[lay-1]*(lad-1)+det-1)].
109 // In this way a lot of space is saved over trying to keep a three
110 // dimensional array fNlayersXmax(fNlad)Xmax(fNdet), since the number
111 // of detectors typically increases with layer number.
114 // A pointer to an array of TObjects containing the detailed shape
115 // information for each type of detector used in the ITS. For example
116 // I have created AliITSgeomSPD, AliITSgeomSDD, and AliITSgeomSSD as
117 // example structures, derived from TObjects, to hold the detector
118 // information. I would recommend that one element in each of these
119 // structures, that which describes the shape of the active volume,
120 // be one of the ROOT classes derived from TShape. In this way it would
121 // be easy to have the display program display the correct active
122 // ITS volumes. See the example classes AliITSgeomSPD, AliITSgeomSDD,
123 // and AliITSgeomSSD for a more detailed example.
128 // The default constructor for the AliITSgeom class. It, by default,
129 // sets fNlayers to zero and zeros all pointers.
131 // AliITSgeom(const char *filename)
132 // The constructor for the AliITSgeom class. All of the data to fill
133 // this structure is read in from the file given my the input filename.
135 // AliITSgeom(AliITSgeom &source)
136 // The copy constructor for the AliITSgeom class. It calls the
137 // = operator function. See the = operator function for more details.
139 // void operator=(AliITSgeom &source)
140 // The = operator function for the AliITSgeom class. It makes an
141 // independent copy of the class in such a way that any changes made
142 // to the copied class will not affect the source class in any way.
143 // This is required for many ITS alignment studies where the copied
144 // class is then modified by introducing some misalignment.
147 // The destructor for the AliITSgeom class. If the arrays fNlad,
148 // fNdet, or fg have had memory allocated to them, there pointer values
149 // are non zero, then this memory space is freed and they are set
150 // to zero. In addition, fNlayers is set to zero. The destruction of
151 // TObjArray fShape is, by default, handled by the TObjArray destructor.
153 // Int_t GetNdetectors(Int_t layer)
154 // This function returns the number of detectors/ladder for a give
155 // layer. In particular it returns fNdet[layer-1].
157 // Int_t GetNladders(Int_t layer)
158 // This function returns the number of ladders for a give layer. In
159 // particular it returns fNlad[layer-1].
161 // Int_t GetNlayers()
162 // This function returns the number of layers defined in the ITS
163 // geometry. In particular it returns fNlayers.
165 // GetAngles(Int_t layer,Int_t ladder,Int_t detector,
166 // Float_t &rx, Float_t &ry, Float_t &rz)
167 // This function returns the rotation angles for a give detector on
168 // a give ladder in a give layer in the three floating point variables
169 // provided. rx = frx, fy = fry, rz = frz. The angles are in radians
171 // GetTrans(Int_t layer,Int_t ladder,Int_t detector,
172 // Float_t &x, Float_t &y, Float_t &z)
173 // This function returns the Cartesian translation for a give
174 // detector on a give ladder in a give layer in the three floating
175 // point variables provided. x = fx0, y = fy0, z = fz0. The units are
176 // those of the Monte Carlo, generally cm.
178 // SetByAngles(Int_t layer,Int_t ladder,Int_t detector,
179 // Float_t &rx, Float_t &ry, Float_t &rz)
180 // This function computes a new rotation matrix based on the angles
181 // rx, ry, and rz (in radians) for a give detector on the give ladder
182 // in the give layer. A new
183 // fg[layer-1][(fNlad[layer-1]*(ladder-1)+detector-1)].fr[] array is
186 // SetTrans(Int_t layer,Int_t ladder,Int_t detector,
187 // Float_t x, Float_t y, Float_t z)
188 // This function sets a new translation vector, given by the three
189 // variables x, y, and z, for the Cartesian coordinate transformation
190 // for the detector defined by layer, ladder and detector.
192 // GetRotMatrix(Int_t layer, Int_t ladder, Int_t detector, Float_t *mat)
193 // Returns, in the Float_t array pointed to by mat, the full rotation
194 // matrix for the give detector defined by layer, ladder, and detector.
195 // It returns all nine elements of fr in the ITS_geom structure. See the
196 // description of the ITS_geom structure for further details of this
199 // GtoL(Int_t layer, Int_t ladder, Int_t detector,
200 // const Float_t *g, Float_t *l)
201 // The function that does the global ALICE Cartesian coordinate
202 // to local active volume detector Cartesian coordinate transformation.
203 // The local detector coordinate system is determined by the layer,
204 // ladder, and detector numbers. The global coordinates are entered by
205 // the three element Float_t array g and the local coordinate values
206 // are returned by the three element Float_t array l. The order of the
207 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
209 // GtoL(const Int_t *Id, const Float_t *g, Float_t *l)
210 // The function that does the global ALICE Cartesian coordinate
211 // to local active volume detector Cartesian coordinate transformation.
212 // The local detector coordinate system is determined by the three
213 // element array Id containing as it's three elements Id[0]=layer,
214 // Id[1]=ladder, and Id[2]=detector numbers. The global coordinates
215 // are entered by the three element Float_t array g and the local
216 // coordinate values are returned by the three element Float_t array l.
217 // The order of the three elements are g[0]=x, g[1]=y, and g[2]=z,
220 // LtoG(Int_t layer, Int_t ladder, Int_t detector,
221 // const Float_t *l, Float_t *g)
222 // The function that does the local active volume detector Cartesian
223 // coordinate to global ALICE Cartesian coordinate transformation.
224 // The local detector coordinate system is determined by the layer,
225 // ladder, and detector numbers. The local coordinates are entered by
226 // the three element Float_t array l and the global coordinate values
227 // are returned by the three element Float_t array g. The order of the
228 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
230 // LtoG(const Int_t *Id, const Float_t *l, Float_t *g)
231 // The function that does the local active volume detector Cartesian
232 // coordinate to global ALICE Cartesian coordinate transformation.
233 // The local detector coordinate system is determined by the three
234 // element array Id containing as it's three elements Id[0]=layer,
235 // Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
236 // are entered by the three element Float_t array l and the global
237 // coordinate values are returned by the three element Float_t array g.
238 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
242 // This function returns the version number of this AliITSgeom
245 // AddShape(TObject *shape)
246 // This function adds one more shape element to the TObjArray
247 // fShape. It is primarily used in the constructor functions of the
248 // AliITSgeom class. The pointer *shape can be the pointer to any
249 // class that is derived from TObject (this is true for nearly every
250 // ROOT class). This does not appear to be working properly at this time.
252 // PrintComparison(FILE *fp, AliITSgeom *other)
253 // This function was primarily created for diagnostic reasons. It
254 // print to a file pointed to by the file pointer fp the difference
255 // between two AliITSgeom classes. The format of the file is basicly,
256 // define d? to be the difference between the same element of the two
257 // classes. For example dfrx = this->fg[i][j].frx - other->fg[i][j].frx.
258 // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then print
259 // layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
260 // if(at least one of the 9 elements of dfr[] are non zero) then print
261 // layer ladder detector dfr[0] dfr[1] dfr[2]
262 // dfr[3] dfr[4] dfr[5]
263 // dfr[6] dfr[7] dfr[8]
264 // Only non zero values are printed to save space. The differences are
265 // typical written to a file because there are usually a lot of numbers
266 // printed out and it is usually easier to read them in some nice editor
267 // rather than zooming quickly past you on a screen. fprintf is used to
268 // do the printing. The fShapeIndex difference is not printed at this time.
270 // PrintData(FILE *fp, Int_t layer, Int_t ladder, Int_t detector)
271 // This function prints out the coordinate transformations for
272 // the particular detector defined by layer, ladder, and detector
273 // to the file pointed to by the File pointer fp. fprinf statements
274 // are used to print out the numbers. The format is
275 // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz Shape=fShapeIndex
276 // dfr= fr[0] fr[1] fr[2]
277 // dfr= fr[3] fr[4] fr[5]
278 // dfr= fr[6] fr[7] fr[8]
279 // By indicating which detector, some control over the information
280 // is given to the user. The output it written to the file pointed
281 // to by the file pointer fp. This can be set to stdout if you want.
283 // Streamer(TBuffer &R__b)
284 // The default Streamer function "written by ROOT" doesn't write out
285 // the arrays referenced by pointers. Therefore, a specific Streamer function
286 // has to be written. This function should not be modified but instead added
287 // on to so that older versions can still be read. The proper handling of
288 // the version dependent streamer function hasn't been written do to the lack
289 // of finding an example at the time of writting.
291 //----------------------------------------------------------------------
293 // The following member functions are defined to modify an existing
294 // AliITSgeom data structure. They were developed for the use in doing
295 // alignment studies of the ITS.
297 // GlobalChange(Float_t *dtranslation, Float_t *drotation)
298 // This function performs a Cartesian translation and rotation of
299 // the full ITS from its default position by an amount determined by
300 // the three element arrays dtranslation and drotation. If every element
301 // of dtranslation and drotation are zero then there is no change made
302 // the geometry. The change is global in that the exact same translation
303 // and rotation is done to every detector element in the exact same way.
304 // The units of the translation are those of the Monte Carlo, usually cm,
305 // and those of the rotation are in radians. The elements of dtranslation
306 // are dtranslation[0] = x, dtranslation[1] = y, and dtranslation[2] = z.
307 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
308 // drotation[2] = rz. A change in x will move the hole ITS in the ALICE
309 // global x direction, the same for a change in y. A change in z will
310 // result in a translation of the ITS as a hole up or down the beam line.
311 // A change in the angles will result in the inclination of the ITS with
312 // respect to the beam line, except for an effective rotation about the
313 // beam axis which will just rotate the ITS as a hole about the beam axis.
315 // GlobalCylindericalChange(Float_t *dtranslation, Float_t *drotation)
316 // This function performs a cylindrical translation and rotation of
317 // each ITS element by a fixed about in radius, rphi, and z from its
318 // default position by an amount determined by the three element arrays
319 // dtranslation and drotation. If every element of dtranslation and
320 // drotation are zero then there is no change made the geometry. The
321 // change is global in that the exact same distance change in translation
322 // and rotation is done to every detector element in the exact same way.
323 // The units of the translation are those of the Monte Carlo, usually cm,
324 // and those of the rotation are in radians. The elements of dtranslation
325 // are dtranslation[0] = r, dtranslation[1] = rphi, and dtranslation[2] = z.
326 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
327 // drotation[2] = rz. A change in r will results in the increase of the
328 // radius of each layer by the same about. A change in rphi will results in
329 // the rotation of each layer by a different angle but by the same
330 // circumferential distance. A change in z will result in a translation
331 // of the ITS as a hole up or down the beam line. A change in the angles
332 // will result in the inclination of the ITS with respect to the beam
333 // line, except for an effective rotation about the beam axis which will
334 // just rotate the ITS as a hole about the beam axis.
336 // RandomChange(Float_t *stranslation, Float_t *srotation)
337 // This function performs a Gaussian random displacement and/or
338 // rotation about the present global position of each active
339 // volume/detector of the ITS. The sigma of the random displacement
340 // is determined by the three element array stranslation, for the
341 // x y and z translations, and the three element array srotation,
342 // for the three rotation about the axis x y and z.
344 // RandomCylindericalChange(Float_t *stranslation, Float_t *srotation)
345 // This function performs a Gaussian random displacement and/or
346 // rotation about the present global position of each active
347 // volume/detector of the ITS. The sigma of the random displacement
348 // is determined by the three element array stranslation, for the
349 // r rphi and z translations, and the three element array srotation,
350 // for the three rotation about the axis x y and z. This random change
351 // in detector position allow for the simulation of a random uncertainty
352 // in the detector positions of the ITS.
353 ////////////////////////////////////////////////////////////////////////
355 Int_t fNlayers; // The number of layers.
356 Int_t *fNlad; // Array of the number of ladders/layer(layer)
357 Int_t *fNdet; // Array of the number of detectors/ladder(layer)
358 ITS_geom **fg; // Structure of translation and rotation.
359 TObjArray *fShape; // Array of shapes and detector information.
362 AliITSgeom(); // Default constructor
363 AliITSgeom(const char *filename); // Constructor
364 AliITSgeom(AliITSgeom &source); // Copy constructor
365 void operator=(AliITSgeom &source);// = operator
366 virtual ~AliITSgeom(); // Default destructor
367 // this is a dummy routine for now.
368 inline Int_t GetNdetectors(Int_t layer) {return fNdet[layer-1];}
369 inline Int_t GetNladders(Int_t layer) {return fNlad[layer-1];}
370 inline Int_t GetNlayers() {return fNlayers;}
371 inline void GetAngles(Int_t lay,Int_t lad,Int_t det,
372 Float_t &rx,Float_t &ry,Float_t &rz){
373 rx = fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].frx;
374 ry = fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].fry;
375 rz = fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].frz;}
376 inline void GetTrans(Int_t lay,Int_t lad,Int_t det,
377 Float_t &x,Float_t &y,Float_t &z){
378 x = fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].fx0;
379 y = fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].fy0;
380 z = fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].fz0;}
381 void SetByAngles(Int_t lay,Int_t lad,Int_t det,
382 Float_t rx,Float_t ry,Float_t rz);
383 inline void SetTrans(Int_t lay,Int_t lad,Int_t det,
384 Float_t x,Float_t y,Float_t z){
385 fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].fx0 = x;
386 fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].fy0 = y;
387 fg[lay-1][fNdet[lay-1]*(lad-1)+det-1].fz0 = z;}
388 void GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Float_t *mat);
389 void GtoL(Int_t lay,Int_t lad,Int_t det,const Float_t *g,Float_t *l);
390 void GtoL(const Int_t *id,const Float_t *g,Float_t *l);
391 void GtoL(const Int_t index,const Float_t *g,Float_t *l);
392 void GtoLMomentum(Int_t lay,Int_t lad,Int_t det,const Float_t *g,Float_t *l);
393 void LtoG(Int_t lay,Int_t lad,Int_t det,const Float_t *l,Float_t *g);
394 void LtoG(const Int_t *id,const Float_t *l,Float_t *g);
395 void LtoG(const Int_t index,const Float_t *l,Float_t *g);
396 void LtoGMomentum(Int_t lay,Int_t lad,Int_t det,const Float_t *l,Float_t *g);
397 Int_t GetModuleIndex(Int_t lay,Int_t lad,Int_t det);
398 void GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det);
399 void GlobalChange(Float_t *tran,Float_t *rot);
400 void GlobalCylindericalChange(Float_t *tran,Float_t *rot);
401 void RandomChange(Float_t *stran,Float_t *srot);
402 void RandomCylindericalChange(Float_t *stran,Float_t *srot);
403 void PrintComparison(FILE *fp,AliITSgeom *other);
404 void PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det);
405 ofstream &PrintGeom(ofstream &out);
406 ifstream &ReadGeom(ifstream &in);
407 virtual Int_t IsVersion() const {return 0;}
408 inline void AddShape(TObject *shp){fShape->AddLast(shp);}
410 ClassDef(AliITSgeom,1)