/*
$Log$
+Revision 1.12 2003/01/14 10:50:19 alibrary
+Cleanup of STEER coding conventions
+
Revision 1.11 2002/10/23 07:24:56 alibrary
Introducing Riostream.h
//
// Digit Response (noise, threshold, saturation, ...)
AliMUONResponse * response = iChamber->ResponseModel();
- q = response->DigitResponse(q);
+ q = response->DigitResponse(q,address);
if (!q) continue;
/*
$Log$
+Revision 1.4 2002/10/14 14:57:29 hristov
+Merging the VirtualMC branch to the main development branch (HEAD)
+
Revision 1.2.10.1 2002/10/11 06:56:47 hristov
Updating VirtualMC to v3-09-02
ClassImp(AliMUONFactory)
-
-void AliMUONFactory::Build(AliMUON* where, const char* what)
+//__________________________________________________________________________
+AliMUONFactory::AliMUONFactory()
+ : TObject(),
+ fMUON(0),
+ fResponse0(0)
{
//
-// Construct MUON from chambers, segmentation and responses
-//
- char tmp[20];
- AliMUON* pMUON = where;
- strcpy(tmp, what);
+}
- if (strcmp(tmp, "default")==0) {
- if(pMUON->GetDebug()) {
-
- printf("\nAliMUONFactory: --------AliMUONFactory------------------------------");
- printf("\nAliMUONFactory: Non default version of MUON selected ");
- printf("\nAliMUONFactory: You have to construct yourself the MUON elements !!");
- printf("\nAliMUONFactory: ----------------------------------------------------");
- }
- pMUON->SetIshunt(0);
- pMUON->SetMaxStepGas(0.1);
- pMUON->SetMaxStepAlu(0.1);
+//__________________________________________________________________________
+AliMUONFactory::~AliMUONFactory()
+{
//
-// Version 0
+}
+
+//__________________________________________________________________________
+void AliMUONFactory::BuildCommon()
+{
//
-// First define the number of planes that are segmented (1 or 2) by a call
-// to SetNsec.
-// Then chose for each chamber (chamber plane) the segmentation
-// and response model.
-// They should be equal for the two chambers of each station. In a future
-// version this will be enforced.
+// Construct the default response.
//
-//
- Int_t chamber;
+
// Default response: 5 mm of gas
- AliMUONResponseV0* response0 = new AliMUONResponseV0;
- response0->SetSqrtKx3AndDeriveKx2Kx4(0.7131); // sqrt(0.5085)
- response0->SetSqrtKy3AndDeriveKy2Ky4(0.7642); // sqrt(0.5840)
- response0->SetPitch(0.25); // anode-cathode distance
- response0->SetSigmaIntegration(10.);
- response0->SetChargeSlope(50);
- response0->SetChargeSpread(0.18, 0.18);
- response0->SetMaxAdc(4096);
- response0->SetZeroSuppression(6);
-
+ fResponse0 = new AliMUONResponseV0;
+ fResponse0->SetSqrtKx3AndDeriveKx2Kx4(0.7131); // sqrt(0.5085)
+ fResponse0->SetSqrtKy3AndDeriveKy2Ky4(0.7642); // sqrt(0.5840)
+ fResponse0->SetPitch(0.25); // anode-cathode distance
+ fResponse0->SetSigmaIntegration(10.);
+ fResponse0->SetChargeSlope(50);
+ fResponse0->SetChargeSpread(0.18, 0.18);
+ fResponse0->SetMaxAdc(4096);
+ fResponse0->SetZeroSuppression(6);
+}
+
+//__________________________________________________________________________
+void AliMUONFactory::BuildStation1()
+{
+//--------------------------------------------------------
+// Configuration for Chamber TC1/2 (Station 1) ----------
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
// Response for 4 mm of gas (station 1)
// automatic consistency with width of sensitive medium in CreateGeometry ????
AliMUONResponseV0* responseSt1 = new AliMUONResponseV0;
responseSt1->SetMaxAdc(4096);
responseSt1->SetZeroSuppression(6);
-//--------------------------------------------------------
-// Configuration for Chamber TC1/2 (Station 1) ----------
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ //--------------------------------------------------------
+ // Configuration for Chamber TC1/2 (Station 1) ----------
+
Float_t rseg1[4]={17.5, 55.2, 71.3, 95.5};
Int_t nseg1[4]={4, 4, 2, 1};
//
- chamber=1;
-// ^^^^^^^^^
- pMUON->SetNsec(chamber-1,2);
+ Int_t chamber=1;
+// ^^^^^^^^^^^^^^^^
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationV01 *seg11=new AliMUONSegmentationV01(4);
seg11->SetDAnod(0.20); // smaller distance between anode wires
seg11->SetPadDivision(nseg1);
- pMUON->SetSegmentationModel(chamber-1, 1, seg11);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg11);
AliMUONSegmentationV02 *seg12=new AliMUONSegmentationV02(4);
seg12->SetSegRadii(rseg1);
seg12->SetDAnod(0.20); // smaller distance between anode wires
seg12->SetPadDivision(nseg1);
- pMUON->SetSegmentationModel(chamber-1, 2, seg12);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg12);
- pMUON->SetResponseModel(chamber-1, responseSt1); // special response
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetResponseModel(chamber-1, responseSt1); // special response
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
chamber=2;
// ^^^^^^^^^
//
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationV01 *seg21=new AliMUONSegmentationV01(4);
seg21->SetSegRadii(rseg1);
seg21->SetPadSize(2.4, 0.4); // smaller pad size
seg21->SetDAnod(0.20); // smaller distance between anode wires
seg21->SetPadDivision(nseg1);
- pMUON->SetSegmentationModel(chamber-1, 1, seg21);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg21);
//
AliMUONSegmentationV02 *seg22=new AliMUONSegmentationV02(4);
seg22->SetSegRadii(rseg1);
seg22->SetPadSize(0.6, 1.6); // smaller pad size
seg22->SetDAnod(0.20); // smaller distance between anode wires
seg22->SetPadDivision(nseg1);
- pMUON->SetSegmentationModel(chamber-1, 2, seg22);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg22);
- pMUON->SetResponseModel(chamber-1, responseSt1); // special response
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetResponseModel(chamber-1, responseSt1); // special response
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+}
+
+//__________________________________________________________________________
+void AliMUONFactory::BuildStation2()
+{
//
//--------------------------------------------------------
// Configuration for Chamber TC3/4 (Station 2) -----------
///^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Float_t rseg2[4]={23.5, 87.7, 122.4, 122.5};
+
Float_t rseg2[4]={23.5, 53.5, 90.5, 122.5};
Int_t nseg2[4]={4, 4, 2, 1};
//
- chamber=3;
-// ^^^^^^^^^
- pMUON->SetNsec(chamber-1,2);
+ Int_t chamber=3;
+// ^^^^^^^^^^^^^^^^
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationV01 *seg31=new AliMUONSegmentationV01(4);
seg31->SetSegRadii(rseg2);
seg31->SetPadSize(3.0, 0.5);
seg31->SetDAnod(3.0/3./4);
seg31->SetPadDivision(nseg2);
- pMUON->SetSegmentationModel(chamber-1, 1, seg31);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg31);
//
AliMUONSegmentationV02 *seg32=new AliMUONSegmentationV02(4);
seg32->SetSegRadii(rseg2);
seg32->SetPadDivision(nseg2);
seg32->SetDAnod(3.0/3./4);
- pMUON->SetSegmentationModel(chamber-1, 2, seg32);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg32);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
chamber=4;
// ^^^^^^^^^
//
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationV01 *seg41=new AliMUONSegmentationV01(4);
seg41->SetSegRadii(rseg2);
seg41->SetPadSize(3.0, 0.5);
seg41->SetDAnod(3.0/3./4);
seg41->SetPadDivision(nseg2);
- pMUON->SetSegmentationModel(chamber-1, 1, seg41);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg41);
//
AliMUONSegmentationV02 *seg42=new AliMUONSegmentationV02(4);
seg42->SetSegRadii(rseg2);
seg42->SetPadDivision(nseg2);
seg42->SetDAnod(3.0/3./4);
- pMUON->SetSegmentationModel(chamber-1, 2, seg42);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg42);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+}
+//__________________________________________________________________________
+void AliMUONFactory::BuildStation3()
+{
//--------------------------------------------------------
// Configuration for Chamber TC5/6 (Station 3) ----------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
Int_t nseg3[4]={4, 4, 2, 1};
Int_t npcb5[36] = {0,0,2,0,
0,0,3,0,
Float_t xpos5[9] = {2., 2., 2., 2.,33., 2., 2., 2., 2.};
Float_t ypos5 = -(20.+4.*(40.-2.*shift));
- chamber=5;
- pMUON->SetNsec(chamber-1,2);
+ Int_t chamber=5;
+ fMUON->SetNsec(chamber-1,2);
AliMUONSegmentationSlat *seg51=new AliMUONSegmentationSlat(4);
seg51->SetNSlats(9);
seg51->SetShift(shift);
seg51->SetPadSize(10.,0.5);
seg51->SetDAnod(0.25);
seg51->SetPadDivision(nseg3);
- pMUON->SetSegmentationModel(chamber-1, 1, seg51);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg51);
AliMUONSegmentationSlatN *seg52=new AliMUONSegmentationSlatN(4);
seg52->SetNSlats(9);
seg52->SetPadSize(1., 10.); // DeltaX(non bending) = 2 * DeltaY(bending)
seg52->SetDAnod(0.25);
seg52->SetPadDivision(nseg3);
- pMUON->SetSegmentationModel(chamber-1, 2, seg52);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetSegmentationModel(chamber-1, 2, seg52);
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
chamber=6;
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
AliMUONSegmentationSlat *seg61=new AliMUONSegmentationSlat(4);
seg61->SetNSlats(9);
seg61->SetShift(shift);
seg61->SetPadSize(10.,0.5);
seg61->SetDAnod(0.25);
seg61->SetPadDivision(nseg3);
- pMUON->SetSegmentationModel(chamber-1, 1, seg61);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg61);
AliMUONSegmentationSlatN *seg62=new AliMUONSegmentationSlatN(4);
seg62->SetNSlats(9);
seg62->SetPadSize(1., 10.); // DeltaX(non bending) = 2 * DeltaY(bending)
seg62->SetDAnod(0.25);
seg62->SetPadDivision(nseg3);
- pMUON->SetSegmentationModel(chamber-1, 2, seg62);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetSegmentationModel(chamber-1, 2, seg62);
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+}
+
+//__________________________________________________________________________
+void AliMUONFactory::BuildStation4()
+{
//--------------------------------------------------------
// Configuration for Chamber TC7/8 (Station 4) ----------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Int_t nseg4[4]={4, 4, 2, 1};
- chamber=7;
-// ^^^^^^^^^
+ Int_t chamber=7;
+// ^^^^^^^^^^^^^^^^
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationSlat *seg71=new AliMUONSegmentationSlat(4);
+ Float_t shift = 1.5/2.;
Int_t npcb7[44] = {0,0,0,3,
0,0,2,2,
0,0,3,2,
seg71->SetPadSize(10.,0.5);
seg71->SetDAnod(0.25);
seg71->SetPadDivision(nseg4);
- pMUON->SetSegmentationModel(chamber-1, 1, seg71);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg71);
AliMUONSegmentationSlatN *seg72=new AliMUONSegmentationSlatN(4);
- pMUON->SetSegmentationModel(chamber-1, 2, seg72);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg72);
seg72->SetNSlats(11);
seg72->SetShift(shift);
seg72->SetNPCBperSector(npcb7);
seg72->SetDAnod(0.25);
seg72->SetPadDivision(nseg4);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
chamber=8;
// ^^^^^^^^^
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationSlat *seg81=new AliMUONSegmentationSlat(4);
seg81->SetPadSize(10.,0.5);
seg81->SetDAnod(0.25);
seg81->SetPadDivision(nseg4);
- pMUON->SetSegmentationModel(chamber-1, 1, seg81);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg81);
AliMUONSegmentationSlat *seg82=new AliMUONSegmentationSlatN(4);
- pMUON->SetSegmentationModel(chamber-1, 2, seg82);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg82);
seg82->SetNSlats(11);
seg82->SetShift(shift);
seg82->SetNPCBperSector(npcb7);
seg82->SetDAnod(0.25);
seg82->SetPadDivision(nseg4);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
-
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+}
+//__________________________________________________________________________
+void AliMUONFactory::BuildStation5()
+{
//--------------------------------------------------------
// Configuration for Chamber TC9/10 (Station 5) ---------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- chamber=9;
-// ^^^^^^^^^
- pMUON->SetNsec(chamber-1,2);
+ Int_t chamber=9;
+// ^^^^^^^^^^^^^^^^
+
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationSlat *seg91=new AliMUONSegmentationSlat(4);
+
+ Int_t nseg4[4]={4, 4, 2, 1};
+ Float_t shift = 1.5/2.;
Int_t npcb9[52] = {0,0,0,3,
0,0,0,4,
0,0,2,3,
seg91->SetPadSize(10.,0.5);
seg91->SetDAnod(0.25);
seg91->SetPadDivision(nseg4);
- pMUON->SetSegmentationModel(chamber-1, 1, seg91);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg91);
AliMUONSegmentationSlatN *seg92=new AliMUONSegmentationSlatN(4);
- pMUON->SetSegmentationModel(chamber-1, 2, seg92);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg92);
seg92->SetNSlats(13);
seg92->SetShift(shift);
seg92->SetNPCBperSector(npcb9);
seg92->SetDAnod(0.25);
seg92->SetPadDivision(nseg4);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
chamber=10;
// ^^^^^^^^^
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
//
AliMUONSegmentationSlat *seg101=new AliMUONSegmentationSlat(4);
seg101->SetPadSize(10.,0.5);
seg101->SetDAnod(0.25);
seg101->SetPadDivision(nseg4);
- pMUON->SetSegmentationModel(chamber-1, 1, seg101);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg101);
AliMUONSegmentationSlatN *seg102=new AliMUONSegmentationSlatN(4);
- pMUON->SetSegmentationModel(chamber-1, 2, seg102);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg102);
seg102->SetNSlats(13);
seg102->SetShift(shift);
seg102->SetNPCBperSector(npcb9);
seg102->SetDAnod(0.25);
seg102->SetPadDivision(nseg4);
- pMUON->SetResponseModel(chamber-1, response0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+ fMUON->SetResponseModel(chamber-1, fResponse0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0.11); // 11% charge spread
+}
+//__________________________________________________________________________
+void AliMUONFactory::BuildStation6()
+{
//--------------------------------------------------------
// Configuration for Trigger Stations --------------------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
// Cluster-size off
AliMUONResponseTrigger* responseTrigger0 = new AliMUONResponseTrigger;
// Cluster-size on
// AliMUONResponseTriggerV1* responseTrigger0 = new AliMUONResponseTriggerV1;
- chamber=11;
- pMUON->SetNsec(chamber-1,2);
+ Int_t chamber=11;
+ fMUON->SetNsec(chamber-1,2);
AliMUONSegmentationTriggerX *seg111=new AliMUONSegmentationTriggerX;
- pMUON->SetSegmentationModel(chamber-1, 1, seg111);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg111);
AliMUONSegmentationTriggerY *seg112=new AliMUONSegmentationTriggerY;
- pMUON->SetSegmentationModel(chamber-1, 2, seg112);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg112);
- pMUON->SetResponseModel(chamber-1, responseTrigger0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
+ fMUON->SetResponseModel(chamber-1, responseTrigger0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
chamber=12;
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
AliMUONSegmentationTriggerX *seg121=new AliMUONSegmentationTriggerX;
- pMUON->SetSegmentationModel(chamber-1, 1, seg121);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg121);
AliMUONSegmentationTriggerY *seg122=new AliMUONSegmentationTriggerY;
- pMUON->SetSegmentationModel(chamber-1, 2, seg122);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg122);
- pMUON->SetResponseModel(chamber-1, responseTrigger0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
+ fMUON->SetResponseModel(chamber-1, responseTrigger0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
chamber=13;
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
AliMUONSegmentationTriggerX *seg131=new AliMUONSegmentationTriggerX;
- pMUON->SetSegmentationModel(chamber-1, 1, seg131);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg131);
AliMUONSegmentationTriggerY *seg132=new AliMUONSegmentationTriggerY;
- pMUON->SetSegmentationModel(chamber-1, 2, seg132);
- pMUON->SetResponseModel(chamber-1, responseTrigger0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
+ fMUON->SetSegmentationModel(chamber-1, 2, seg132);
+ fMUON->SetResponseModel(chamber-1, responseTrigger0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
chamber=14;
- pMUON->SetNsec(chamber-1,2);
+ fMUON->SetNsec(chamber-1,2);
AliMUONSegmentationTriggerX *seg141=new AliMUONSegmentationTriggerX;
- pMUON->SetSegmentationModel(chamber-1, 1, seg141);
+ fMUON->SetSegmentationModel(chamber-1, 1, seg141);
AliMUONSegmentationTriggerY *seg142=new AliMUONSegmentationTriggerY;
- pMUON->SetSegmentationModel(chamber-1, 2, seg142);
+ fMUON->SetSegmentationModel(chamber-1, 2, seg142);
- pMUON->SetResponseModel(chamber-1, responseTrigger0);
- pMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
- } else {
- if(pMUON->GetDebug()) {
+ fMUON->SetResponseModel(chamber-1, responseTrigger0);
+ fMUON->Chamber(chamber-1).SetChargeCorrel(0); // same charge on cathodes
+}
+
+//__________________________________________________________________________
+void AliMUONFactory::Build(AliMUON* where, const char* what)
+{
+//
+// Construct MUON from chambers, segmentation and responses
+//
+
+ fMUON = where;
+ char tmp[20];
+ strcpy(tmp, what);
+
+ if (strcmp(tmp, "default")==0) {
+ // Set default parameters
+ fMUON->SetIshunt(0);
+ fMUON->SetMaxStepGas(0.1);
+ fMUON->SetMaxStepAlu(0.1);
+
+ // Build all stations
+ BuildCommon();
+ BuildStation1();
+ BuildStation2();
+ BuildStation3();
+ BuildStation4();
+ BuildStation5();
+ BuildStation6();
+ }
+ else {
+ if(fMUON->GetDebug()) {
printf("\nAliMUONFactory: --------AliMUONFactory------------------------------");
printf("\nAliMUONFactory: Non default version of MUON selected ");
printf("\nAliMUONFactory: You have to construct yourself the MUON elements !!");
}
}
+//__________________________________________________________________________
+void AliMUONFactory::BuildStation(AliMUON* where, Int_t stationNumber)
+{
+//
+// Construct MUON from chambers, segmentation and responses
+//
+// Version 0
+//
+// First define the number of planes that are segmented (1 or 2) by a call
+// to SetNsec.
+// Then chose for each chamber (chamber plane) the segmentation
+// and response model.
+// They should be equal for the two chambers of each station. In a future
+// version this will be enforced.
+//
+
+ fMUON = where;
+ if (!fResponse0) BuildCommon();
+
+ switch (stationNumber) {
+ case 1: BuildStation1(); break;
+ case 2: BuildStation2(); break;
+ case 3: BuildStation3(); break;
+ case 4: BuildStation4(); break;
+ case 5: BuildStation5(); break;
+ case 6: BuildStation6(); break;
+
+ default: Fatal("Build", "Wrong station number");
+ }
+}
#include "AliDetector.h"
// #include "AliMUONTriggerCircuit.h" // cp
-class AliMUONChamber;
class AliMUON;
+class AliMUONResponseV0;
class AliMUONFactory : public TObject {
+
public:
- static void Build(AliMUON* where, const char* what);
- protected:
- ClassDef(AliMUONFactory,0) // MUON Factory for Chambers and Segmentation
+ AliMUONFactory();
+ virtual ~AliMUONFactory();
+
+ void Build(AliMUON* where, const char* what);
+ void BuildStation(AliMUON* where, Int_t stationNumber);
+
+ private:
+ void BuildCommon();
+ void BuildStation1();
+ void BuildStation2();
+ void BuildStation3();
+ void BuildStation4();
+ void BuildStation5();
+ void BuildStation6();
+
+ // data members
+ AliMUON* fMUON; // MUON detector
+ AliMUONResponseV0* fResponse0; // default response
+
+ ClassDef(AliMUONFactory,0) // MUON Factory for Chambers and Segmentation
};
#endif
/*
$Log$
+Revision 1.10 2003/01/14 10:50:19 alibrary
+Cleanup of STEER coding conventions
+
Revision 1.9 2002/03/13 07:04:11 jchudoba
Connect only MUON branches when reading the event to speed up digitisation.
fHitMap = 0;
fList = 0;
fBgrFile = 0;
+ fDebug = 0;
}
//------------------------------------------------------------------------
//
// Digit Response (noise, threshold, saturation, ...)
AliMUONResponse * response = iChamber->ResponseModel();
- q = response->DigitResponse(q);
+ q = response->DigitResponse(q,address);
if (!q) continue;
Int_t nptracks = address->GetNTracks();
if (nptracks > kMAXTRACKS) {
- printf("\n Attention - nptracks > kMAXTRACKS %d \n", nptracks);
+ if (fDebug>0)
+ printf("\n Attention - nptracks > kMAXTRACKS %d \n", nptracks);
nptracks = kMAXTRACKS;
}
if (nptracks > 2) {
- printf("Attention - nptracks > 2 %d \n",nptracks);
- printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,fDigits[0],fDigits[1],q);
+ if (fDebug>0) {
+ printf("Attention - nptracks > 2 %d \n",nptracks);
+ printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,fDigits[0],fDigits[1],q);
+ }
}
for (Int_t tr = 0; tr < nptracks; tr++) {
tracks[tr] = address->GetTrack(tr);
void SetBackgroundEventNumber(Int_t i) {fEvNrBgr = i;}
void SetBackgroundFileName(char* file) {fFnBgr = file;}
void SetMode(MergeMode_t mode) {fMerge = mode;}
+ void SetDebug(Int_t debug) {fDebug = debug;}
enum {kBgTag = -1};
MergeMode_t fMerge; // merging type kDigitize, kMerge
char *fFnBgr; // background file name
TFile *fBgrFile; // Pointer to background file
+ Int_t fDebug; // level of debug printing
ClassDef(AliMUONMerger,0)
};
class TF1;
class AliSegmentation;
-
+class AliMUONTransientDigit;
class AliMUONResponse :
public TObject {
// Charge disintegration
virtual Float_t IntXY(AliSegmentation *) =0;
// Noise, zero-suppression, adc saturation
- virtual Int_t DigitResponse(Int_t digit) =0;
+ //virtual Int_t DigitResponse(Int_t digit) =0;
+ virtual Int_t DigitResponse(Int_t digit,
+ AliMUONTransientDigit* where) =0;
//
ClassDef(AliMUONResponse,1) // Chamber response virtual base class
};
/*
$Log$
+Revision 1.6 2000/12/04 17:48:23 gosset
+Modifications for stations 1 et 2 mainly:
+* station 1 with 4 mm gas gap and smaller cathode segmentation...
+* stations 1 and 2 with "grey" frame crosses
+* mean noise at 1.5 ADC channel
+* Ar-CO2 gas (80%+20%)
+
Revision 1.5 2000/11/21 13:47:55 gosset
All Mathieson parameters (Sqrt(K3), K2 and K4) set in one function,
SetSqrtKx3AndDeriveKx2Kx4 or SetSqrtKx3AndDeriveKx2Kx4,
fKy4*(TMath::ATan(uy2)-TMath::ATan(uy1)));
}
-Int_t AliMUONResponseV0::DigitResponse(Int_t digit)
+Int_t AliMUONResponseV0::DigitResponse(Int_t digit, AliMUONTransientDigit* where)
{
// add white noise and do zero-suppression and signal truncation
// Float_t meanNoise = gRandom->Gaus(1, 0.2);
// Charge disintegration
virtual Float_t IntXY(AliSegmentation * segmentation);
// Noise, zero-suppression, adc saturation
- virtual Int_t DigitResponse(Int_t digit);
+ virtual Int_t DigitResponse(Int_t digit, AliMUONTransientDigit* where);
ClassDef(AliMUONResponseV0,1) // Implementation of Mathieson response
protected:
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1Decoder
+// -----------------------
+// A generic set of functions (defined in the <decoder> namespace).
+// Used to decode formatted strings, eg. a list of integer ranges,
+// or a list of sub-strings separated by delimiters such as '(','{','[', ... .
+// Example:
+// (string 1) (string 2) [string3] {string4} [ (string5.1) (string5.2) ]
+// note : |_____________________|
+// |
+// this is just ONE substring.
+
+
+#include "AliMUONSt1Decoder.h"
+
+using namespace std;
+
+//_____________________________________________________________________
+vector<string> decoder::SplitNtuples(const string& s,
+ const string& leftSep,
+ const string& rightSep)
+
+{
+// separate substrings in <s>, by using the first level of delimiters
+// given in the argument
+// Example:
+// (string 1) (string 2) [string3] {string4} [ (string5.1) (string5.2) ]
+// returns a list of 5 substrings
+// "string 1"
+// "string 2"
+// "string 3"
+// "string 4" and
+// " (string5.1) (string5.2) "
+// --
+ vector<string> ans;
+ string::size_type idx = 0;
+ do {
+ idx = s.find_first_of(leftSep,idx);
+ if (idx != string::npos) {
+ string::size_type sepNum = leftSep.find_first_of(s[idx],0);
+ if (sepNum>=rightSep.length()){
+ idx++;
+ continue;
+ }
+ int count=1;
+ string::size_type idx2 = idx+1;
+ while ((count>0) && (idx2<s.length())){
+ if (s[idx2] == leftSep[sepNum]) count++;
+ if (s[idx2] == rightSep[sepNum]) count--;
+ idx2++;
+ }
+ if (count != 0) return ans; // bad format...stop here
+ ans.push_back(s.substr(idx+1,idx2-idx-2));
+ idx=idx2;
+ }
+ } while (idx != string::npos);
+ return ans;
+}
+
+//_____________________________________________________________________
+vector<string> decoder::SplitList(const string& s,const string& sep)
+{
+// split <s> into several substrings, by using any of the delimters in <sep>
+// Example : str1 ; str2 , str3
+// gives a list of 3 substrings ("str1", "str2" and "str3") if
+// the delimiter parameter is ",;"
+// and a list of 2 substrings ("str1","str2,str3") if
+// the delimiter parameter is ";"
+// --
+ vector<string> ans;
+ string::size_type i=0,j;
+ while ((j=s.find_first_of(sep,i))!=string::npos){
+ ans.push_back(s.substr(i,j-i));
+ i=j+1;
+ }
+ ans.push_back(s.substr(i,s.length()-i));
+ return ans;
+}
+
+//_____________________________________________________________________
+vector<int>
+decoder::DecodeListRanges(const string& s,const string& sep,const string& rangeSep)
+{
+// decode <s> as a list of integers
+// Example: 192/199 ; -10/-7
+// gives a list of 12 integers:
+// 192, 193, 194, 195, 196, 197, 198, 199, -10, -9, -8, -7
+// --
+ vector<int> ans;
+ vector< pair <int,int> > rangeList = DecodeListOfIntRanges(s,sep,rangeSep);
+ for (unsigned int i = 0 ;i<rangeList.size();i++){
+ for (int j=rangeList[i].first;j<=rangeList[i].second;j++){
+ ans.push_back(j);
+ }
+ }
+ return ans;
+}
+
+//_____________________________________________________________________
+vector< pair <int,int> >
+decoder::DecodeListOfIntRanges(const string& s,const string& sep,const string& rangeSep)
+{
+// decodes <s> as a list of int ranges
+// Example: 192/303 ; -10/-1
+// gives a list of two int pairs:
+// pair(192,303) and another pair (-10,-1)
+// --
+ string::size_type i=0;
+ vector< pair <int,int> > ans;
+ if (s.empty()) return ans;
+
+ vector<string> parts = decoder::SplitList(s,sep);
+
+ for (unsigned int k=0;k<parts.size();k++){
+ i=parts[k].find_first_of(rangeSep);
+ int from,to;
+ if (i == string::npos) {
+ from = atoi(parts[k].c_str());
+ to = from;
+ } else {
+ from=atoi(parts[k].substr(0,i).c_str());
+ to =atoi(parts[k].substr(i+1,parts[k].length()-i-1).c_str());
+ }
+ ans.push_back(pair<int,int>(from,to));
+ }
+ return ans;
+}
+
+//_____________________________________________________________________
+vector< pair <double,double> >
+decoder::DecodeListOfFloatRanges(const string& s,const string& sep,const string& rangeSep)
+{
+// decodes <s> as a list of double (floating point) ranges
+// Example : 192.33/303.26 ; -10.2/-1.41
+// gives a list of two double precision floating point (phew!) pairs:
+// pair (192.33,303.26) and another pair (-10.2,-1.41)
+// --
+ string::size_type i=0;
+ vector< pair <double,double> > ans;
+ if (s.empty()) return ans;
+
+ vector<string> parts = decoder::SplitList(s,sep);
+
+ for (unsigned int k=0;k<parts.size();k++){
+ i=parts[k].find_first_of(rangeSep);
+ double from,to;
+ if (i == string::npos) {
+ from = atof(parts[k].c_str());
+ to = from;
+ } else {
+ from=atof(parts[k].substr(0,i).c_str());
+ to =atof(parts[k].substr(i+1,parts[k].length()-i-1).c_str());
+ }
+ ans.push_back(pair<double,double>(from,to));
+ }
+ return ans;
+}
--- /dev/null
+#ifndef ALI_MUON_ST1_DECODER_H
+#define ALI_MUON_ST1_DECODER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1Decoder
+// -----------------------
+// A generic set of functions (defined in the <decoder> namespace).
+// Used to decode formatted strings, eg. a list of integer ranges,
+// or a list of sub-strings separated by delimiters such as '(','{','[', ... .
+// Example:
+// (string 1) (string 2) [string3] {string4} [ (string5.1) (string5.2) ]
+// note : |_____________________|
+// |
+// this is just ONE substring.
+
+
+#include <vector>
+#include <utility>
+#include <string>
+#include <cstdlib>
+
+namespace decoder
+{
+ using std::vector;
+ using std::pair;
+ using std::string;
+ vector<string> SplitNtuples(const string& s,
+ const string& leftSep ="({[\"'/",
+ const string& rightSep=")}]\"'/");
+ vector<string> SplitList(const string& s,const string& sep=";,");
+ vector<int> DecodeListRanges(const string& s,const string& sep=";,",const string& rangeSep="/");
+ vector< pair<int,int> > DecodeListOfIntRanges(const string& s,const string& sep=";,",const string& rangeSep="/");
+ vector< pair<double,double> > DecodeListOfFloatRanges(const string& s,const string& sep=";,",const string& rangeSep="/");
+}
+
+#endif //ALI_MUON_ST1_DECODER_H
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1ElectronicElement
+// ---------------------------------
+// Describes a set of pads either by defining
+// a range of indices, or
+// a range of (centimeters) positions or
+// a range of electronic channel numbers or
+// a range of MANU numbers or, finally,
+// a range of gassiplex/MANAS numbers, in a given range of MANU addresses
+
+#include "AliMUONSt1ElectronicElement.h"
+
+ClassImp(AliMUONSt1ElectronicElement);
+
+//______________________________________________________________________________
+AliMUONSt1ElectronicElement::AliMUONSt1ElectronicElement()
+ :TObject(),fDescription(kNone)
+{
+// default constructor
+}
+
+//______________________________________________________________________________
+AliMUONSt1ElectronicElement::AliMUONSt1ElectronicElement(TDescription descr)
+ :TObject(),fDescription(descr)
+{
+// normal constructor
+ switch (descr){
+ case kXY : SetRange(0,0.,0.); SetRange(1,0.,0.); break;
+ default: SetRange(0,0,0); SetRange(1,0,0); break;
+ }
+}
+
+//______________________________________________________________________________
+AliMUONSt1ElectronicElement::~AliMUONSt1ElectronicElement()
+{
+// destructor
+}
+
+//______________________________________________________________________________
+void AliMUONSt1ElectronicElement::SetRange(Int_t numVar,Int_t i1,Int_t i2)
+{
+// set the range of the <numVar>th variables, in all cases but kXY
+// ---
+
+ if (fDescription==kXY) {
+ fRanges[numVar][0].x = (Double_t)i1;
+ fRanges[numVar][1].x = (Double_t)i2;
+ } else {
+ fRanges[numVar][0].i = i1;
+ fRanges[numVar][1].i = i2;
+ }
+}
+
+//______________________________________________________________________________
+void AliMUONSt1ElectronicElement::SetRange(Int_t numVar,Double_t x1,Double_t x2)
+{
+// set the range of the <numVar>th variable, in cases kXY
+// ---
+
+ if (fDescription==kXY) {
+ fRanges[numVar][0].x = x1;
+ fRanges[numVar][1].x = x2;
+ } else {
+ fRanges[numVar][0].i = (Int_t)x1;
+ fRanges[numVar][1].i = (Int_t)x2;
+ }
+}
+
+//______________________________________________________________________________
+Bool_t AliMUONSt1ElectronicElement::IsInRange(Int_t numVar,Int_t i) const
+{
+// is the given value in the <numVar>th variable
+// ---
+
+ return (fRanges[numVar][0].i<=i) && (fRanges[numVar][1].i>=i);
+}
+
+//______________________________________________________________________________
+Bool_t AliMUONSt1ElectronicElement::IsInRange(Int_t numVar,Double_t x) const
+{
+// is the given value in the <numVar>th variable
+// ---
+
+ return (fRanges[numVar][0].x<=x) && (fRanges[numVar][1].x>=x);
+}
+
+//______________________________________________________________________________
+Bool_t AliMUONSt1ElectronicElement::Contains(const MPad& pad) const
+{
+// is the pad <pad> contained in this range
+// ---
+
+ switch(fDescription){
+ case kNone:
+ return kFALSE;
+ case kIJ :
+ return ( IsInRange(0,pad.GetIndices().GetFirst())
+ && IsInRange(1,pad.GetIndices().GetSecond())
+ );
+ case kXY :
+ return ( IsInRange(0,pad.Position().X())
+ && IsInRange(1,pad.Position().Y())
+ );
+ case kMGC :
+ return ( IsInRange(0,pad.GetLocation().GetFirst())
+ && IsInRange(1,pad.GetLocation().GetSecond())
+ );
+ case kMG :
+ return ( IsInRange(0,pad.GetLocation().GetFirst())
+ && IsInRange(1,pad.GetLocation().GetSecond() >> 4)
+ );
+ case kM :
+ return ( IsInRange(0,pad.GetLocation().GetFirst()));
+
+ default: return kFALSE;
+ }
+}
--- /dev/null
+#ifndef ALI_MUON_ST1_ELECTRONIC_ELEMENT_H
+#define ALI_MUON_ST1_ELECTRONIC_ELEMENT_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1ElectronicElement
+// ---------------------------------
+// Describes a set of pads either by defining
+// a range of indices, or
+// a range of (centimeters) positions or
+// a range of electronic channel numbers or
+// a range of MANU numbers or, finally,
+// a range of gassiplex/MANAS numbers, in a given range of MANU addresses
+
+#include <MPad.h>
+
+class AliMUONSt1ElectronicElement : public TObject
+{
+ public:
+ enum TDescription {kNone, kIJ, kXY, kMGC, kMG, kM};
+
+ public:
+ AliMUONSt1ElectronicElement();
+ AliMUONSt1ElectronicElement(TDescription descr);
+ virtual ~AliMUONSt1ElectronicElement();
+
+ // methods
+ Bool_t Contains(const MPad& pad) const;
+ void SetRange(Int_t numVar,Int_t i1,Int_t i2);
+ void SetRange(Int_t numVar,Double_t x1,Double_t x2);
+ Bool_t IsInRange(Int_t numVar,Int_t i) const;
+ Bool_t IsInRange(Int_t numVar,Double_t x) const;
+
+ private:
+ typedef union {Int_t i; Double_t x;} TData;
+
+ TDescription fDescription; // how the pad range is described
+ TData fRanges[2][2]; // range of the 2 variables
+
+ ClassDef(AliMUONSt1ElectronicElement,1) //range of electronic elements
+};
+#endif //ALI_MUON_ST1_ELECTRONIC_ELEMENT_H
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONIniReader
+// ----------------------
+// General class to read data in ASCII file format,
+// similar to the Windows ".ini" files (a set of sections tagged by a
+// [ sectionName ]
+// and values defined in the way:
+// parameterName = value
+//
+// comment lines can be introduced if the first non-blank character
+// is either ';' or '#'
+
+#include <iostream>
+#include <sstream>
+
+#include "AliMUONSt1IniReader.h"
+
+using namespace std;
+
+//______________________________________________________________________
+AliMUONSt1IniReader::AliMUONSt1IniReader()
+ :fFile(),fCurrentType(kUndef),fEndOfFile(true)
+{
+// default constructor
+// ---
+}
+
+//______________________________________________________________________
+AliMUONSt1IniReader::AliMUONSt1IniReader(string fileName)
+{
+// normal constructor
+// ---
+
+ fFile.open(fileName.c_str());
+ if (!fFile) {cerr<<"Unable to open file "<<fileName<<endl;}
+ fEndOfFile = !fFile.good();
+ fCurrentType=kUndef;
+}
+
+//______________________________________________________________________
+AliMUONSt1IniReader::~AliMUONSt1IniReader()
+{
+ //destructor
+ fFile.close();
+}
+
+//______________________________________________________________________
+void AliMUONSt1IniReader::Reset()
+{
+// Reset the input stream. The file can be re-read after calling this function
+// ---
+
+ fFile.clear();
+ fFile.seekg(0,ios::beg);
+ fCurrentType=kUndef;
+ fEndOfFile=!fFile.good();
+}
+
+//______________________________________________________________________
+bool AliMUONSt1IniReader::ReadNextLine()
+{
+// The main function of this class.
+// Read next line in the file and set CurrentType(), CurrentName() and
+// CurrentValue() with the line's content
+// ---
+
+ if ( (!fFile) || (fFile.eof()) || (!fFile.good()) )
+ {fEndOfFile=true; fCurrentType=kUndef; return false;}
+
+ string line;
+ getline(fFile,line);
+ if ( line.empty()) { // this is a blank line
+ return ReadNextLine();
+ }
+ istringstream l(line);
+
+ char c;
+
+ l>>c;
+ if ( (c==';') || (c=='#') ) { // this is a comment
+ return ReadNextLine();
+ }
+
+ if (c=='[') { // this is a chapter name
+ getline(l,fCurrentName,']');
+ fCurrentName=trail(fCurrentName);
+ fCurrentType=kChapter;
+ return true;
+ } else {
+ if (line.find_first_of("=") != string::npos ) {
+ l.putback(c);
+ getline(l,fCurrentName,'=');
+ fCurrentName = trail(fCurrentName);
+
+ getline(l,fCurrentValue);
+ fCurrentValue = trail(fCurrentValue);
+ fCurrentType=kValue;
+ return true;
+ } else {
+ cerr<<"Warning, badly formated line..."<<line<<endl;
+ fCurrentType=kUndef;
+ return false;
+ }
+ }
+ fCurrentType=kUndef;
+ return false;
+}
+
+//______________________________________________________________________
+AliMUONSt1IniReader::TValueList AliMUONSt1IniReader::MakeCurrentValueList()
+{
+// Read the next lines in the file
+// until eof() or a new section is found.
+// Return the list of (name,value) pairs read.
+// ---
+
+ TValueList ans;
+ while (true){
+ if (fCurrentType==kValue){
+ ans.push_back( TValuePair(fCurrentName,fCurrentValue));
+ } else break;
+ ReadNextLine();
+ }
+ return ans;
+}
+
+//______________________________________________________________________
+AliMUONSt1IniReader::TChapter AliMUONSt1IniReader::MakeCurrentChapter()
+{
+// Searches in the rest file for a new section
+// and return it's name and the list of (name,value) pairs in it
+// ---
+
+ while ((!Eof()) && (fCurrentType != kChapter)) ReadNextLine();
+ if (Eof()) return TChapter();
+ string name = fCurrentName;
+ ReadNextLine();
+ return TChapter(name,MakeCurrentValueList());
+}
+
+//______________________________________________________________________
+AliMUONSt1IniReader::TChapterList AliMUONSt1IniReader::MakeChapterList()
+{
+// Read the rest of the file and return all the chapter names and
+// (name,value) pair lists found after the current position
+// ---
+
+ TChapterList ans;
+ while (true) {
+ if (fCurrentType==kChapter) {
+ string s= fCurrentName;
+ ReadNextLine();
+ ans.insert(TChapter(s,MakeCurrentValueList()));
+ } else ReadNextLine();
+ if (fEndOfFile) break;
+ }
+ return ans;
+}
+
+//______________________________________________________________________
+string AliMUONSt1IniReader::trail(const string& s) const
+{
+// Utility function: clear the blanks before and after the string <s>
+// ---
+
+ string::size_type p1=s.find_first_not_of(" ");
+ if (p1==string::npos) return "";
+ string::size_type p2=s.find_last_not_of(" ");
+ return s.substr(p1,p2-p1+1);
+}
--- /dev/null
+#ifndef ALI_MUON_ST1_INI_READER_H
+#define ALI_MUON_ST1_INI_READER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONIniReader
+// ----------------------
+// General class to read data in ASCII file format,
+// similar to the Windows ".ini" files (a set of sections tagged by a
+// [ sectionName ]
+// and values defined in the way:
+// parameterName = value
+//
+// comment lines can be introduced if the first non-blank character
+// is either ';' or '#'
+
+
+#include <string>
+#include <vector>
+#include <map>
+#include <utility>
+#include <fstream>
+
+using std::string;
+using std::vector;
+using std::multimap;
+using std::ifstream;
+using std::pair;
+
+class AliMUONSt1IniReader
+{
+ public:
+ enum TType {kUndef,kChapter,kValue};
+ typedef pair<string,string> TValuePair;
+ typedef vector<TValuePair> TValueList;
+ typedef pair<string,TValueList> TChapter;
+ typedef multimap <string,TValueList> TChapterList;
+
+ public:
+ AliMUONSt1IniReader();
+ AliMUONSt1IniReader(string fileName);
+ virtual ~AliMUONSt1IniReader();
+
+ bool ReadNextLine();
+ TType GetCurrentType() const {return fCurrentType; }
+ string GetCurrentName() const {return fCurrentName; }
+ string GetCurrentValue() const {return fCurrentValue;}
+ TChapter MakeCurrentChapter();
+ TValueList MakeCurrentValueList();
+ TChapterList MakeChapterList();
+ bool Eof() {return fEndOfFile;}
+ void Reset() ;
+
+ private:
+ string trail(const string& s) const;
+
+ ifstream fFile; // the file to be read
+ TType fCurrentType; // current type of line (either kChapter or kValue)
+ string fCurrentName; // name of chapter / name of parameter pair
+ string fCurrentValue;// value of the parameter pair if the type is kValue
+ bool fEndOfFile; // true if the file is entirely read
+};
+
+#endif //ALI_MUON_ST1_INI_READER_H
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1Response
+// ----------------------------
+// Response class for station 1 including electronics and detector response.
+// Individual pedestals or noise levels can be controlled separately.
+// The current pulse height responses do not contain any physics
+
+#include <vector>
+#include <cstdlib>
+#include <TMath.h>
+#include <TRandom.h>
+#include <TSystem.h>
+#include <MIntPair.h>
+#include <MPlaneSegmentation.h>
+#include <MPad.h>
+#include <MMotifMap.h>
+#include <MSector.h>
+#include <MPlane.h>
+#include <MZone.h>
+#include <MSubZone.h>
+#include <MVRowSegment.h>
+#include "AliMUONSt1Response.h"
+#include "AliMUONSt1ResponseParameter.h"
+#include "AliMUONSt1ResponseRule.h"
+#include "AliMUONSt1IniReader.h"
+#include "AliMUONSt1Decoder.h"
+#include "AliMUONTransientDigit.h"
+
+ClassImp(AliMUONSt1Response);
+
+const TString AliMUONSt1Response::fgkConfigBaseName = "configChamber";
+const TString AliMUONSt1Response::fgkStandardIniFileName = "st1StdParameter.ini";
+
+const TString AliMUONSt1Response::fgkBaseName ="base";
+const TString AliMUONSt1Response::fgkIncludeName ="include";
+const TString AliMUONSt1Response::fgkParameterName ="parameter";
+const TString AliMUONSt1Response::fgkRegionName ="region";
+const TString AliMUONSt1Response::fgkRuleName ="rule";
+const TString AliMUONSt1Response::fgkNameName ="name";
+const TString AliMUONSt1Response::fgkPedestalName ="pedestal";
+const TString AliMUONSt1Response::fgkNoiseName ="noise";
+const TString AliMUONSt1Response::fgkStateName ="state";
+const TString AliMUONSt1Response::fgkMName ="padM";
+const TString AliMUONSt1Response::fgkMGName ="padMG";
+const TString AliMUONSt1Response::fgkMGCName ="padMGC";
+const TString AliMUONSt1Response::fgkIJName ="padIJ";
+const TString AliMUONSt1Response::fgkXYName ="padXY";
+const TString AliMUONSt1Response::fgkZoneName ="zone";
+const TString AliMUONSt1Response::fgkStickyOnName ="stickyOn";
+const TString AliMUONSt1Response::fgkStickyOffName ="stickyOff";
+const TString AliMUONSt1Response::fgkFileName ="file";
+const TString AliMUONSt1Response::fgkValueName ="value";
+const TString AliMUONSt1Response::fgkGausName ="gaus";
+const TString AliMUONSt1Response::fgkNotName ="no";
+const TString AliMUONSt1Response::fgkNofSigmaName ="nofSigma";
+
+
+
+//__________________________________________________________________________
+AliMUONSt1Response::AliMUONSt1Response(Int_t chamber)
+ :AliMUONResponseV0()
+ ,fChamber(chamber),fParams(),fRegions(),fTrashList()
+
+{
+ // default pedestal value
+ fCountNofCalls=0;
+ fCountUnknownZone=0;
+ fCountUnknownIndices=0;
+
+ Int_t i;
+ for (i=0;i<2;i++){
+ fIniFileName[i]="";
+ fPlane[0]=0;
+ fPlaneSegmentation[i]=0;
+ for (Int_t j=0;j<fgkNofZones;j++)
+ {
+ fDefaultParameters[i][j]=0;
+ }
+ }
+ fTrashList.SetOwner(kTRUE);
+}
+
+
+//__________________________________________________________________________
+AliMUONSt1Response::~AliMUONSt1Response()
+{
+//destructor
+ Int_t i;
+ for (i=0;i<2;i++){
+ if (fPlaneSegmentation[i]) delete fPlaneSegmentation[i];
+ if (fPlane[i]) delete fPlane[i];
+ fTrashList.Delete();
+ }
+}
+
+//__________________________________________________________________________
+void AliMUONSt1Response::SetIniFileName(Int_t plane,const TString& fileName)
+{
+// Set the file to be read for the response parameters
+ if ((plane>=0) && (plane<=1)) fIniFileName[plane] = fileName;
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::ReadCouplesOfIntRanges(const string& value,TList* list,AliMUONSt1ElectronicElement::TDescription descr)
+{
+// Decode couplets of integer ranges (enclosed within parenthesis and
+// separated by a comma, eg. (12/20,33/60) for ranges 12 to 20 and 33 to 60)
+// and save these ranges in <list>
+ vector<string> lstCpl = decoder::SplitNtuples(value);
+ for (unsigned int n=0;n<lstCpl.size();n++){ // for each (..,..) couplet
+ vector<string> lst = decoder::SplitList(lstCpl[n],",");
+ // should have 2 elements
+ if (lst.size() != 2) {
+ Warning("ReadIniFile","Bad pad definition");
+ continue;
+ }
+ vector<pair <int,int> > lst1 = decoder::DecodeListOfIntRanges(lst[0],";");
+ vector<pair <int,int> > lst2 = decoder::DecodeListOfIntRanges(lst[1],";");
+ for (unsigned int u1=0;u1<lst1.size();u1++){
+ for (unsigned int u2=0;u2<lst2.size();u2++){
+ AliMUONSt1ElectronicElement* elem
+ = new AliMUONSt1ElectronicElement(descr);
+ fTrashList.Add(elem);
+ elem->SetRange(0,lst1[u1].first,lst1[u1].second);
+ elem->SetRange(1,lst2[u2].first,lst2[u2].second);
+ list->Add(elem);
+ }
+ }
+ }
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::ReadCouplesOfFloatRanges(const string& value,TList* list)
+{
+// Decode couplets of floating point ranges (enclosed within parenthesis and
+// separated by a comma, eg. (12./20.,33./60.) for ranges 12. to 20. and 33. to 60.)
+// and save these ranges in <list>
+ vector<string> lstCpl = decoder::SplitNtuples(value);
+ for (unsigned int n=0;n<lstCpl.size();n++){ // for each (..,..) couplets
+ vector<string> lst = decoder::SplitList(lstCpl[n],",");
+ // should have 2 elements
+ if (lst.size() != 2) {
+ Warning("ReadIniFile","Bad pad definition");
+ continue;
+ }
+ vector<pair <double,double> > lst1 = decoder::DecodeListOfFloatRanges(lst[0],";");
+ vector<pair <double,double> > lst2 = decoder::DecodeListOfFloatRanges(lst[1],";");
+ for (unsigned int u1=0;u1<lst1.size();u1++){
+ for (unsigned int u2=0;u2<lst2.size();u2++){
+ AliMUONSt1ElectronicElement* elem
+ = new AliMUONSt1ElectronicElement(AliMUONSt1ElectronicElement::kXY);
+ fTrashList.Add(elem);
+ elem->SetRange(0,lst1[u1].first,lst1[u1].second);
+ elem->SetRange(1,lst2[u2].first,lst2[u2].second);
+ list->Add(elem);
+ }
+ }
+ }
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::SetPairToParam(const string& name,const string& value,AliMUONSt1ResponseParameter* param) const
+{
+// set a (name,value) pair to <param>
+ TString path=getenv("ALICE_ROOT");
+ path+="/MUON/";
+ const char* nm = name.c_str();
+ if (fgkStateName.CompareTo(nm,TString::kIgnoreCase)==0){
+ param->SetState(atoi(value.c_str()));
+ } else if (fgkPedestalName.CompareTo(nm,TString::kIgnoreCase)==0){
+ vector<string> lst = decoder::SplitList(value," ");
+ if ((lst.size()>0) && (fgkNotName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
+ param->UnSetPedestal();
+ } else if ((lst.size()>1) && (fgkValueName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
+ param->SetPedestal(atof(lst[1].c_str()));
+ } else if ((lst.size()>1) && (fgkFileName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
+ param->SetPedestal(path+lst[1].c_str());
+ } else if ((lst.size()>2) && (fgkGausName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
+ param->SetPedestal(atof(lst[1].c_str()),atof(lst[2].c_str()));
+ }
+ } else if (fgkNoiseName.CompareTo(nm,TString::kIgnoreCase)==0){
+ vector<string> lst = decoder::SplitList(value," ");
+ if ((lst.size()>1) && (fgkValueName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
+ param->SetNoise(atof(lst[1].c_str()));
+ } else if ((lst.size()>1) && (fgkFileName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
+ param->SetNoise(path+lst[1].c_str());
+ } else if ((lst.size()>2) && (fgkGausName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
+ param->SetNoise(atof(lst[1].c_str()),atof(lst[2].c_str()));
+ }
+ } else if (fgkNofSigmaName.CompareTo(nm,TString::kIgnoreCase)==0){
+ param->SetNofSigma(atoi(value.c_str()));
+ } else if (fgkStickyOnName.CompareTo(nm,TString::kIgnoreCase)==0){
+ vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
+ for (unsigned int i=0;i<lst.size();i++){
+ for (int j=lst[i].first;(j<12) && (j<=lst[i].second);j++){
+ param->SetStickyBitOn(j);
+ }
+ }
+ } else if (fgkStickyOffName.CompareTo(nm,TString::kIgnoreCase)==0){
+ vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
+ for (unsigned int i=0;i<lst.size();i++){
+ for (int j=lst[i].first;(j<12) && (j<=lst[i].second);j++){
+ param->SetStickyBitOff(j);
+ }
+ }
+ }
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::SetPairToListElem(const string& name,const string& value,TList* list)
+{
+// set a (name,value) pair to <list>
+ const char* nm = name.c_str();
+ if (fgkIJName.CompareTo(nm,TString::kIgnoreCase)==0){
+ ReadCouplesOfIntRanges(value,list,AliMUONSt1ElectronicElement::kIJ);
+ } else if (fgkMGCName.CompareTo(nm,TString::kIgnoreCase)==0){
+ ReadCouplesOfIntRanges(value,list,AliMUONSt1ElectronicElement::kMGC);
+ } else if (fgkMGName.CompareTo(nm,TString::kIgnoreCase)==0){
+ ReadCouplesOfIntRanges(value,list,AliMUONSt1ElectronicElement::kMG);
+ } else if (fgkMName.CompareTo(nm,TString::kIgnoreCase)==0){
+ vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
+ for (unsigned int i=0;i<lst.size();i++){
+ AliMUONSt1ElectronicElement* elem
+ = new AliMUONSt1ElectronicElement(AliMUONSt1ElectronicElement::kM);
+ fTrashList.Add(elem);
+ elem->SetRange(0,lst[i].first,lst[i].second);
+ list->Add(elem);
+ }
+ } else if (fgkXYName.CompareTo(nm,TString::kIgnoreCase)==0){
+ ReadCouplesOfFloatRanges(value,list);
+ }
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::ReadIniFile(Int_t plane)
+{
+ //Read the ini file and fill the <plane>th structures
+ TString path=getenv("ALICE_ROOT");
+ path+="/MUON/";
+ //read .ini file
+ if (gSystem->AccessPathName(path+fIniFileName[plane],kReadPermission)){
+ Fatal("ReadIniFile",
+ Form("Unable to Read the file %s",fIniFileName[plane].Data()));
+ return;
+ }
+ fRegions.clear();
+ fParams.clear();
+ ReadIniFile(plane,path+fIniFileName[plane],kTRUE,kTRUE,kTRUE);
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::ReadIniFile(Int_t plane,const TString& fileName,
+ Bool_t rdParam,Bool_t rdRegion,Bool_t rdRule)
+{
+ //Read the given ini file and fill the <plane>th structures
+ cout<<"Reading parameter file "<<fileName<<endl;
+ AliMUONSt1IniReader iniFile(fileName.Data());
+ AliMUONSt1IniReader::TChapter chap;
+ AliMUONSt1IniReader::TValueList vals;
+ AliMUONSt1IniReader::TValueList::iterator itValue;
+ while (!iniFile.Eof()){
+ chap = iniFile.MakeCurrentChapter();
+ TString chapName = chap.first.c_str();
+ vals = chap.second;
+ if (fgkBaseName.CompareTo(chapName,TString::kIgnoreCase)==0){
+ for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
+ string name = (*itValue).first;
+ string value = (*itValue).second;
+ if (fgkIncludeName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
+ vector<string> lst = decoder::SplitList(value,":");
+ if (lst.size()>0){
+ TString inFileName = TString(gSystem->DirName(fileName))+"/" + lst[0].c_str();
+ Bool_t inParam=kFALSE,inRegion=kFALSE,inRule=kFALSE;
+ if (lst.size()>1) {
+ vector<string> lst2 = decoder::SplitList(lst[1],",");
+ for (unsigned int k=0;k<lst2.size();k++){
+ if (fgkParameterName.CompareTo(lst2[k].c_str(),TString::kIgnoreCase)==0){
+ inParam=kTRUE;
+ } else if (fgkRegionName.CompareTo(lst2[k].c_str(),TString::kIgnoreCase)==0){
+ inRegion=kTRUE;
+ } else if (fgkRuleName.CompareTo(lst2[k].c_str(),TString::kIgnoreCase)==0){
+ inRule=kTRUE;
+ }
+ }
+ } else {
+ inParam=inRegion=inRule=kTRUE;
+ }
+ ReadIniFile(plane,inFileName,inParam,inRegion,inRule);
+ }
+ }
+ }
+ } else if (rdParam && fgkParameterName.CompareTo(chapName,TString::kIgnoreCase)==0){
+ AliMUONSt1ResponseParameter* param = new AliMUONSt1ResponseParameter();
+ fTrashList.Add(param);
+ string paramName=Form("Parameter %d",fParams.size()+1);
+ for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
+ string name = (*itValue).first;
+ string value = (*itValue).second;
+ if (fgkNameName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
+ paramName=value;
+ } else SetPairToParam(name,value,param);
+ }
+ fParams[paramName]=param;
+ } else if (rdRegion && fgkRegionName.CompareTo(chapName,TString::kIgnoreCase)==0){
+ TList* lstElem = new TList;
+ string listName=Form("Region %d",fRegions.size()+1);
+ for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
+ string name = (*itValue).first;
+ string value = (*itValue).second;
+ if (fgkNameName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
+ listName=value;
+ } else SetPairToListElem(name,value,lstElem);
+ }
+ fRegions[listName]=lstElem;
+ }
+ }
+ iniFile.Reset();
+ while (!iniFile.Eof()){
+ chap = iniFile.MakeCurrentChapter();
+ TString chapName = chap.first.c_str();
+ vals = chap.second;
+ if (rdRule && fgkRuleName.CompareTo(chapName,TString::kIgnoreCase)==0){
+ Int_t i;
+ Bool_t zones[fgkNofZones];
+ for (i=0;i<fgkNofZones;i++) zones[i]=kFALSE;
+ AliMUONSt1ResponseRule* rule=0;
+ for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
+ string name = (*itValue).first;
+ string value = (*itValue).second;
+ if (fgkZoneName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
+ vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
+ for (unsigned int i=0;i<lst.size();i++){
+ for (int j=lst[i].first;(j<=fgkNofZones) && (j<=lst[i].second);j++) {
+ if (j>0) zones[j-1] = kTRUE;
+ }
+ }
+ } else if (fgkRegionName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
+ TListMap::iterator it = fRegions.find(value);
+ if (it != fRegions.end()){
+ if (!rule) {
+ rule = new AliMUONSt1ResponseRule();
+ fTrashList.Add(rule);
+ }
+ TIter next((*it).second);
+ AliMUONSt1ElectronicElement* el;
+ while ((el = static_cast<AliMUONSt1ElectronicElement*>(next()))){
+ rule->AddElement(el);
+ }
+ } else Warning("ReadIniFile",Form("Can't find region named %s",value.c_str()));
+ }
+ }
+ for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
+ string name = (*itValue).first;
+ string value = (*itValue).second;
+ if (fgkParameterName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
+ TParamsMap::iterator it = fParams.find(value);
+ if (it != fParams.end()){
+ AliMUONSt1ResponseParameter* param = (*it).second;
+ for (i=0;i<fgkNofZones;i++) if (zones[i]) {
+ fDefaultParameters[plane][i]=param;
+ }
+ if (rule) rule->AddParameter(param);
+ } else Warning("ReadIniFile",Form("Can't find parameter named %s",value.c_str()));
+ }
+ }
+ if (rule) fRulesList[plane].AddFirst(rule);
+ }
+ }
+ for (TListMap::iterator it = fRegions.begin() ; it != fRegions.end(); ++it) delete (*it).second;
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::ReadFiles()
+{
+// Define the current response rules with respect to the description
+// given in the "configChamber1.ini" and "configChamber2.ini" files.
+ Int_t i;
+ TString path=getenv("ALICE_ROOT");
+ path+="/MUON/";
+
+ TString configFileName = path + fgkConfigBaseName + Form("%d.ini",fChamber);
+ if (gSystem->AccessPathName(configFileName,kReadPermission)){
+ // no configChamberI.ini file exists
+ SetIniFileName(0,fgkStandardIniFileName);
+ SetIniFileName(1,fgkStandardIniFileName);
+ } else {
+ cout<<"Reading configuration file "<<configFileName<<endl;
+ AliMUONSt1IniReader iniFile(configFileName.Data());
+ while (!iniFile.Eof()) {
+ iniFile.ReadNextLine();
+ if (iniFile.GetCurrentType() != AliMUONSt1IniReader::kValue) continue;
+ Int_t plane;
+ if ((sscanf(iniFile.GetCurrentName().c_str()
+ ,"file%d",&plane)==1) && (plane>=0) && (plane<=1)){
+ SetIniFileName(plane,iniFile.GetCurrentValue().c_str());
+ }
+ }
+ }
+ //book memory and fill them with .ini files
+ fPlane[0]=MPlane::Create(kBendingPlane);
+ fPlane[1]=MPlane::Create(kNonBendingPlane);
+ for (i=0;i<2;i++){
+ fPlaneSegmentation[i]= new MPlaneSegmentation(fPlane[i]);
+ ReadIniFile(i);
+ }
+}
+
+//__________________________________________________________________________
+Float_t AliMUONSt1Response::IntPH(Float_t eloss)
+{
+ // Calculate charge from given ionization energy lost.
+ Int_t nel;
+ nel= Int_t(eloss*1.e9/20);
+ Float_t charge=0;
+ if (nel == 0) nel=1;
+ for (Int_t i=1;i<=nel;i++) {
+ Float_t arg=0.;
+ while(!arg) arg = gRandom->Rndm();
+ charge -= fChargeSlope*TMath::Log(arg);
+ }
+ return charge;
+}
+
+
+//__________________________________________________________________________
+MZone* AliMUONSt1Response::FindZone(MSector* sector,Int_t posId)
+{
+// to be moved to MSector::
+ for (Int_t izone=1;izone<=sector->GetNofZones();izone++){
+ MZone* zone = sector->GetZone(izone);
+ for (Int_t isub=0;isub<zone->GetNofSubZones();isub++){
+ MSubZone* sub=zone->GetSubZone(isub);
+ for (Int_t iseg=0;iseg<sub->GetNofRowSegments();iseg++){
+ if (sub->GetRowSegment(iseg)->HasMotifPosition(posId)) return zone;
+ }
+ }
+ }
+ return 0;
+}
+
+
+//__________________________________________________________________________
+
+Int_t AliMUONSt1Response::DigitResponse(Int_t digit,AliMUONTransientDigit* where)
+{
+ // returns the electronic response of pad located at <where>, when
+ // a charge <digit> is present
+
+ //cout<<"electronic of pad "<<where->PadX()<<' '<<where->PadY()
+ // <<" on plane "<<where->Cathode()<<endl;
+
+ //read the files the first time this function is called
+ if (!fPlane[0]) ReadFiles();
+
+ fCountNofCalls++;
+
+ MIntPair indices(where->PadX(),where->PadY());
+ MPad pad = fPlaneSegmentation[where->Cathode()]->PadByIndices(indices,kFALSE);
+ Int_t GC=0;
+ Int_t numZone=0;
+ MZone* zone=0;
+
+ if (pad.IsValid()) {
+ MIntPair location = pad.GetLocation();
+ //cout<<location.GetFirst()<<endl;
+ Int_t posId=abs(location.GetFirst());
+ MSector* sector=0;
+ if (fPlane[0]->GetFrontSector()->GetMotifMap()->FindMotifPosition(posId))
+ sector=(MSector*)fPlane[0]->GetFrontSector();
+ else if (fPlane[0]->GetBackSector()->GetMotifMap()->FindMotifPosition(posId))
+ sector=(MSector*)fPlane[0]->GetBackSector();
+
+ if (sector) zone=FindZone(sector,posId);
+ if (zone){
+ numZone=zone->GetID()-1;
+ GC=location.GetSecond();
+ } else {
+ fCountUnknownZone++;
+ }
+ } else {
+ fCountUnknownIndices++;
+ }
+
+ if (!zone) {
+ cout<<"Probleme electronic of pad "<<where->PadX()<<' '<<where->PadY()
+ <<" on plane "<<where->Cathode()<<endl;
+ return 6666;
+ }
+ TList listParams;
+ TIter next(&fRulesList[where->Cathode()]);
+ AliMUONSt1ResponseRule* rule;
+ while ( (rule = static_cast<AliMUONSt1ResponseRule*>(next())))
+ if (rule->Contains(pad)) listParams.AddAll(rule->GetParameters());
+ if (fDefaultParameters[where->Cathode()][numZone])
+ listParams.Add(fDefaultParameters[where->Cathode()][numZone]);
+
+ AliMUONSt1ResponseParameter* param;
+ TIter nextParam(&listParams);
+ while ( (param = static_cast<AliMUONSt1ResponseParameter*>(nextParam()))){
+ if (param->GetState()==kFALSE) {
+ return 0;
+ }
+ }
+ nextParam.Reset();
+ while ( (param = static_cast<AliMUONSt1ResponseParameter*>(nextParam()))){
+ if (param->HasPedestal()) {
+ digit = param->ApplyPedestal(digit,GC);
+ break; // Apply pedestals just once --> break the loop once a pedestal
+// rule is applied
+ }
+ }
+ if ( digit < 0) digit=0;
+ if (digit > MaxAdc()) digit=MaxAdc();
+ nextParam.Reset();
+ while ( (param = static_cast<AliMUONSt1ResponseParameter*>(nextParam()))){
+ digit = param->ApplyStickyBits(digit);
+ }
+
+ //cout<<digit<<endl;
+ return digit;
+}
+
+
+//__________________________________________________________________________
+void AliMUONSt1Response::PrintStatistics() const
+{
+// Show the results of the statistics
+ cout<<"The DigitResponse() method was called "<<fCountNofCalls<<" times"<<endl;
+ cout<<" it was unable to find the pad corresponding to the given indices "
+ <<fCountUnknownIndices<<" times ("
+ <<(Double_t)100.*fCountUnknownIndices/fCountNofCalls
+ <<"%)"<<endl;
+ cout<<" it was unable to find the zone corresponding to the found pad "
+ <<fCountUnknownZone<<" times ("
+ <<(Double_t)100.*fCountUnknownZone/fCountNofCalls
+ <<"%)"<<endl;
+}
+
+
+
+
+
+
+
--- /dev/null
+#ifndef ALI_MUON_ST1_RESPONSE_H
+#define ALI_MUON_ST1_RESPONSE_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1Response
+// ----------------------------
+// Response class for station 1 including electronics and detector response.
+// Individual pedestals or noise levels can be controlled separately.
+// The current pulse height responses do not contain any physics
+
+#include <string>
+#include <map>
+#include <TString.h>
+#include <TList.h>
+#include "AliMUONResponseV0.h"
+#include "AliMUONSt1ElectronicElement.h"
+
+using std::string;
+using std::map;
+
+class MPlane;
+class MPlaneSegmentation;
+class MZone;
+class MSector;
+class TArrayF;
+class TObjArray;
+class AliMUONSt1ResponseParameter;
+
+class AliMUONSt1Response : public AliMUONResponseV0
+{
+public:
+ AliMUONSt1Response(Int_t chamber=1);
+ virtual ~AliMUONSt1Response();
+
+ //
+ // Configuration methods
+ //
+ void SetIniFileName(Int_t plane,const TString& fileName);
+
+ virtual Float_t IntPH(Float_t eloss);
+
+ // Noise, zero-suppression, adc saturation
+ virtual Int_t DigitResponse(Int_t digit,AliMUONTransientDigit* where);
+ void PrintStatistics() const;
+
+
+ protected:
+
+ //private types
+ typedef map<string,AliMUONSt1ResponseParameter*> TParamsMap;
+ typedef map<string,TList*> TListMap;
+ static const Int_t fgkNofZones=4;
+ static const TString fgkConfigBaseName;
+ static const TString fgkStandardIniFileName;
+
+ // static names
+ static const TString fgkBaseName ;
+ static const TString fgkIncludeName ;
+ static const TString fgkParameterName ;
+ static const TString fgkRegionName ;
+ static const TString fgkRuleName ;
+ static const TString fgkNameName ;
+ static const TString fgkPedestalName ;
+ static const TString fgkNoiseName ;
+ static const TString fgkStateName ;
+ static const TString fgkMName ;
+ static const TString fgkMGName ;
+ static const TString fgkMGCName ;
+ static const TString fgkIJName ;
+ static const TString fgkXYName ;
+ static const TString fgkZoneName ;
+ static const TString fgkStickyOnName ;
+ static const TString fgkStickyOffName ;
+ static const TString fgkFileName ;
+ static const TString fgkValueName ;
+ static const TString fgkGausName ;
+ static const TString fgkNotName ;
+ static const TString fgkNofSigmaName ;
+
+ //protected methods
+ MZone* FindZone(MSector* sector,Int_t posId); // to be moved in MSector::
+ void ReadFiles();
+ void ReadIniFile(Int_t plane,const TString& fileName,Bool_t rdParam,Bool_t rdRegion,Bool_t rdRule);
+ void ReadIniFile(Int_t plane);
+ void ReadCouplesOfIntRanges(const string& value,TList* list,AliMUONSt1ElectronicElement::TDescription descr);
+ void ReadCouplesOfFloatRanges(const string& value,TList* list);
+ void SetPairToParam(const string& name,const string& value,AliMUONSt1ResponseParameter* param) const;
+ void SetPairToListElem(const string& name,const string& value,TList* list);
+
+
+ //data members
+ MPlane* fPlane[2]; // !The mapping planes
+ MPlaneSegmentation* fPlaneSegmentation[2]; // !The mapping plane segmentation
+ TString fIniFileName[2];// file names for initialisation of each cathode
+
+ AliMUONSt1ResponseParameter* fDefaultParameters[2][fgkNofZones]; // !Response for each zone
+ TList fRulesList[2]; //! list of special rules
+
+ Int_t fCountNofCalls; // number of calls to DigitResponse()
+ Int_t fCountUnknownZone; // ntimes the DigitResponse was called in an unknown zone
+ Int_t fCountUnknownIndices; // ntimes the DigitResponse was called with unknown indices
+
+ Int_t fChamber; // The chamber number
+
+ TParamsMap fParams; //! internal parameter list
+ TListMap fRegions; //! internal list of regions
+ TList fTrashList; //!internal trash list
+
+ ClassDef(AliMUONSt1Response,1) // Overall detector response
+};
+
+#endif //ALI_MUON_ST1_RESPONSE_H
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1ResponseParameter
+// ---------------------------------
+// Describes a set of filters to be applied to a digital value
+// in order to simulate electronics characteristics
+// (pedestal, noise, sticky bits, etc....)
+// Threshold levels for the MANU zero supression algorithm are included.
+
+#include <fstream>
+#include <TRandom.h>
+#include "AliMUONSt1ResponseParameter.h"
+
+ClassImp(AliMUONSt1ResponseParameter);
+
+//_________________________________________________________________________
+AliMUONSt1ResponseParameter::AliMUONSt1ResponseParameter()
+ :TNamed()
+{
+// default constructor
+ fPedestalMode = kNone;
+ fNoiseMode = kNone;
+ fState=1;
+ fNofSigma=3;
+ fStickyOn=fStickyOff=0;
+}
+
+//_________________________________________________________________________
+AliMUONSt1ResponseParameter::AliMUONSt1ResponseParameter(const TString& name,const TString& title)
+:TNamed(name,title)
+{
+// normal constructor
+ fPedestalMode = kNone;
+ fNoiseMode = kNone;
+ fState=1;
+ fNofSigma=3;
+ fStickyOn=fStickyOff=0;
+}
+
+//_________________________________________________________________________
+AliMUONSt1ResponseParameter::~AliMUONSt1ResponseParameter()
+{
+// destructor
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetState(Bool_t state)
+{
+// If set to off, no information will be available from the electronics
+// ---
+
+ fState=state;
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetPedestal(Double_t val)
+{
+// Set pedestal values to a constant
+// ---
+
+ fPedestalMode = kValue;
+ fPedestalParam.value = val;
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetPedestal(Double_t mean,Double_t sigma)
+{
+// Set pedestal values to a parameterized gaussian
+// ---
+
+ fPedestalMode = kGauss;
+ fPedestalParam.gauss.mean = mean;
+ fPedestalParam.gauss.sigma = sigma;
+}
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetPedestal(const TString& fileName)
+{
+// Set pedestal values to those given in a file
+// ---
+
+ ifstream file(fileName.Data());
+ if (file.good()){
+ fPedestalMode = kFile;
+ for (Int_t ch=0;ch<fgkNofChannels;ch++) {
+ Float_t value;
+ file>>value;
+ fPedestalParam.values[ch] = value;
+ //cout<<"Pedestal["<<i<<"]["<<ch<<"]="<<value<<endl;
+ }
+ file.close();
+ } else {
+ Warning("SetPedestal",Form("Can't read file %s",fileName.Data()));
+ SetPedestal(150.,10.);
+ }
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::UnSetPedestal()
+{
+// Set pedestal values to 0.
+// ---
+
+ fPedestalMode=kNone;
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetNoise(Double_t val)
+{
+// Set Noise values to a constant value
+// ---
+
+ fNoiseMode = kValue;
+ fNoiseParam.value = val;
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetNoise(Double_t mean,Double_t sigma)
+{
+// Set Noise values to a parameterized gaussian
+// ---
+
+ fNoiseMode = kGauss;
+ fNoiseParam.gauss.mean = mean;
+ fNoiseParam.gauss.sigma = sigma;
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetNoise(const TString& fileName)
+{
+// Set Noise values to those given in a file
+// ---
+
+ ifstream file(fileName.Data());
+ if (file.good()){
+ fNoiseMode = kFile;
+ for (Int_t ch=0;ch<fgkNofChannels;ch++) {
+ Float_t value;
+ file>>value;
+ fNoiseParam.values[ch] = value;
+ //cout<<"Noise["<<i<<"]["<<ch<<"]="<<value<<endl;
+ }
+ file.close();
+ } else {
+ Warning("SetNoise",Form("Can't read file %s",fileName.Data()));
+ SetNoise(150.,10.);
+ }
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetNofSigma(Int_t nofSigma)
+{
+// set Number of sigmas to be applied as threshold (for zero suppression)
+// ---
+
+ fNofSigma = nofSigma;
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetStickyBitOn (Int_t bit,Int_t val)
+{
+// In the response, this bit will always be set to 1 (unless <State> is off)
+// ---
+
+ if (val)
+ fStickyOn |= (1<<bit);
+ else
+ fStickyOn &= ~(1<<bit);
+}
+
+//_________________________________________________________________________
+void AliMUONSt1ResponseParameter::SetStickyBitOff(Int_t bit,Int_t val)
+{
+// In the response, this bit will always be set to 0
+// ---
+
+ if (val)
+ fStickyOff |= (1<<bit);
+ else
+ fStickyOff &= ~(1<<bit);
+}
+
+//_________________________________________________________________________
+Int_t AliMUONSt1ResponseParameter::ApplyPedestal(Int_t base,Int_t GC) const
+{
+// calculate the response to <base>, with respect to the current pedestal
+// parameters
+// --
+ Double_t ped = Choose(fPedestalMode,fPedestalParam,GC);
+ Double_t nse = Choose(fNoiseMode,fNoiseParam,GC);
+ Double_t noise = gRandom->Gaus(0, nse);
+ base+=(Int_t)(noise + ped);
+ if (base-ped-noise*fNofSigma<0) base=0;
+
+ return base;
+}
+//_________________________________________________________________________
+Int_t AliMUONSt1ResponseParameter::ApplyStickyBits(Int_t base) const
+{
+// set the response to <base>, with respect to the current stickyBits
+// parameters
+// --
+ base |= fStickyOn;
+ base &= (~fStickyOff);
+ return base;
+}
+//////////////////// Privates methods
+//_________________________________________________________________________
+
+Double_t AliMUONSt1ResponseParameter::Choose(TMode mode,TParam param,Int_t GC) const
+{
+// Choose a (pedestal/noise) value to be applied following the parameterization rule
+// ---
+
+ switch (mode){
+ case kNone : return 0;
+ case kValue : return param.value;
+ case kGauss : return gRandom->Gaus(param.gauss.mean,param.gauss.sigma);
+ case kFile : return param.values[GC];
+ }
+ Fatal("Choose","No mode is given");
+ return 0;
+}
--- /dev/null
+#ifndef ALI_MUON_ST1_RESPONSE_PARAMETER_H
+#define ALI_MUON_ST1_RESPONSE_PARAMETER_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1ResponseParameter
+// ---------------------------------
+// Describes a set of filters to be applied to a digital value
+// in order to simulate electronics characteristics
+// (pedestal, noise, sticky bits, etc....)
+// Threshold levels for the MANU zero supression algorithm are included.
+
+#include <TNamed.h>
+#include <TString.h>
+
+class AliMUONSt1ResponseParameter : public TNamed
+{
+ public:
+ AliMUONSt1ResponseParameter();
+ AliMUONSt1ResponseParameter(const TString& name,const TString& title);
+ virtual ~AliMUONSt1ResponseParameter();
+
+ void SetState(Bool_t state) ;
+ void SetPedestal(Double_t val);
+ void SetPedestal(Double_t mean,Double_t sigma);
+ void SetPedestal(const TString& fileName);
+ void UnSetPedestal();
+ void SetNoise(Double_t val);
+ void SetNoise(Double_t mean,Double_t sigma);
+ void SetNoise(const TString& fileName);
+ void SetNofSigma(Int_t nofSigma);
+ void SetStickyBitOn (Int_t bit,Int_t val=1);
+ void SetStickyBitOff(Int_t bit,Int_t val=1);
+ Int_t ApplyPedestal(Int_t base,Int_t GC) const;
+ Int_t ApplyStickyBits(Int_t base) const;
+ Bool_t HasPedestal() const {return fPedestalMode != kNone;}
+ Bool_t GetState() const {return fState;}
+ private:
+ static const Int_t fgkNofChannels=64;
+ typedef enum {kNone,kValue,kGauss,kFile} TMode;
+ typedef struct {Double_t mean; Double_t sigma;} TGaussParam;
+ typedef union {
+ Double_t values[fgkNofChannels];
+ Double_t value;
+ TGaussParam gauss;
+ } TParam;
+
+ Double_t Choose(TMode mode,TParam param,Int_t GC) const;
+ TMode fPedestalMode; // mode for pedestal values
+ TParam fPedestalParam; // pedestal access parameters
+ TMode fNoiseMode; // mode for noise values
+ TParam fNoiseParam; // noise access parameters
+ Int_t fNofSigma; // No of sigma for threshold (zero supression)
+ Bool_t fState; // is the element on/off
+ Int_t fStickyOn; // which bits are always on (mask) .
+ Int_t fStickyOff; // which bits are always off (mask).
+
+ ClassDef(AliMUONSt1ResponseParameter,1) // electronics parmeters for Response
+};
+#endif //ALI_MUON_ST1_RESPONSE_PARAMETER_H
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1ResponseRule
+// -----------------------------
+// Describes a response rule.
+// A "rule" is defined as being a set of electronic filters to be applied
+// (ie. a set of AliMUONSt1ResponseParameter) and a set of cathode pads to
+// which these filters should be applied (set of AliMUONSt1ElectronicElement)
+
+#include "AliMUONSt1ResponseRule.h"
+#include "AliMUONSt1ElectronicElement.h"
+#include "AliMUONSt1ResponseParameter.h"
+
+ClassImp(AliMUONSt1ResponseRule);
+
+//__________________________________________________________________________
+AliMUONSt1ResponseRule::AliMUONSt1ResponseRule()
+ : TObject(),
+ fElementList(),
+ fParameters()
+{
+// default constructor
+}
+
+//__________________________________________________________________________
+AliMUONSt1ResponseRule::~AliMUONSt1ResponseRule()
+{
+// destructor
+}
+
+//__________________________________________________________________________
+void AliMUONSt1ResponseRule::AddElement(AliMUONSt1ElectronicElement* element)
+{
+// Add an electronic element to the list
+// ---
+
+ fElementList.Add(element);
+}
+
+//__________________________________________________________________________
+void AliMUONSt1ResponseRule::AddParameter(AliMUONSt1ResponseParameter* param)
+{
+// Add an electronics parameter for this rule
+// ---
+
+ fParameters.Add(param);
+}
+
+//__________________________________________________________________________
+Bool_t AliMUONSt1ResponseRule::Contains(const MPad& pad) const
+{
+// Is this pad is contained in this rule's list
+// ---
+
+ TIter next(&fElementList);
+ AliMUONSt1ElectronicElement* el;
+ while ((el = static_cast<AliMUONSt1ElectronicElement*>(next()))){
+ if (el->Contains(pad)) return kTRUE;
+ }
+ return kFALSE;
+}
--- /dev/null
+#ifndef ALI_MUON_ST1_RESPONSE_RULE_H
+#define ALI_MUON_ST1_RESPONSE_RULE_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1ResponseRule
+// -----------------------------
+// Describes a response rule.
+// A "rule" is defined as being a set of electronic filters to be applied
+// (ie. a set of AliMUONSt1ResponseParameter) and a set of cathode pads to
+// which these filters should be applied (set of AliMUONSt1ElectronicElement)
+
+#include <TObject.h>
+#include <TList.h>
+#include <MPad.h>
+
+class AliMUONSt1ElectronicElement;
+class AliMUONSt1ResponseParameter;
+
+class AliMUONSt1ResponseRule : public TObject
+{
+ public:
+ AliMUONSt1ResponseRule();
+ virtual ~AliMUONSt1ResponseRule();
+
+ void AddElement(AliMUONSt1ElectronicElement* element);
+ void AddParameter(AliMUONSt1ResponseParameter* param);
+ Bool_t Contains(const MPad& pad) const;
+ TList* GetParameters() {return &fParameters;}
+
+ private:
+ TList fElementList;// list of electronic elements to which this rule is applied
+ TList fParameters; // parameters for this rule
+
+ ClassDef(AliMUONSt1ResponseRule,1) // A set of electronic elements and the linked electronic parameters
+};
+
+#endif //ALI_MUON_ST1_RESPONSE_RULE_H
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1Segmentation
+// ------------------------------
+// Segmentation for MUON station 1 using the external
+// mapping package
+
+#include <cmath>
+
+#include <Riostream.h>
+#include <TError.h>
+#include <TObjArray.h>
+#include <TVector2.h>
+#include <TF1.h>
+
+#include <MPlane.h>
+#include <MPlaneType.h>
+#include <MPlaneSegmentation.h>
+#include <MPlaneAreaPadIterator.h>
+#include <MSector.h>
+#include <MZone.h>
+#include <MConstants.h>
+
+#include "AliMUONSt1Segmentation.h"
+#include "AliRun.h"
+#include "AliMUON.h"
+#include "AliMUONChamber.h"
+
+ClassImp(AliMUONSt1Segmentation)
+
+const Float_t AliMUONSt1Segmentation::fgkWireD = 0.20;
+const Float_t AliMUONSt1Segmentation::fgkLengthUnit = 0.1;
+
+//______________________________________________________________________________
+AliMUONSt1Segmentation::AliMUONSt1Segmentation(const MPlaneType planeType)
+: AliSegmentation(),
+ fPlane(0),
+ fPlaneSegmentation(0),
+ fPlaneIterator(0),
+ fWireD(fgkWireD),
+ fChamber(0),
+ fId(0),
+ fRmin(0.),
+ fRmax(0.),
+ fZ(0.),
+ fIx(0),
+ fIy(0),
+ fX(0.),
+ fY(0.),
+ fSector(0),
+ fXhit(0.),
+ fYhit(0.),
+ fIxt(0),
+ fIyt(0),
+ fIwt(0),
+ fXt(0.),
+ fYt(0.),
+ fCorrA(0)
+{
+// Normal constructor
+ fPlane = MPlane::Create(planeType);
+ fPlaneSegmentation = new MPlaneSegmentation(fPlane);
+
+ fCorrA = new TObjArray(3);
+ fCorrA->AddAt(0,0);
+ fCorrA->AddAt(0,1);
+ fCorrA->AddAt(0,2);
+}
+
+//______________________________________________________________________________
+AliMUONSt1Segmentation::AliMUONSt1Segmentation()
+: AliSegmentation(),
+ fPlane(0),
+ fPlaneSegmentation(0),
+ fPlaneIterator(0),
+ fWireD(fgkWireD),
+ fChamber(0),
+ fId(0),
+ fRmin(0.),
+ fRmax(0.),
+ fZ(0.),
+ fIx(0),
+ fIy(0),
+ fX(0.),
+ fY(0.),
+ fSector(0),
+ fXhit(0.),
+ fYhit(0.),
+ fIxt(0),
+ fIyt(0),
+ fIwt(0),
+ fXt(0.),
+ fYt(0.),
+ fCorrA(0) {
+// Default Constructor
+}
+
+//______________________________________________________________________________
+AliMUONSt1Segmentation::AliMUONSt1Segmentation(const AliMUONSt1Segmentation& rhs)
+{
+// Copy constructor
+ Fatal("Copy constructor",
+ "Copy constructor is not implemented.");
+}
+
+//______________________________________________________________________________
+AliMUONSt1Segmentation::~AliMUONSt1Segmentation() {
+// Destructor
+
+ delete fPlane;
+ delete fPlaneSegmentation;
+ delete fPlaneIterator;
+}
+
+//
+// operators
+//
+
+//______________________________________________________________________________
+AliMUONSt1Segmentation&
+AliMUONSt1Segmentation::operator=(const AliMUONSt1Segmentation& rhs)
+{
+// Copy operator
+
+ // check assignement to self
+ if (this == &rhs) return *this;
+
+ Fatal("operator=",
+ "Assignment operator is not implemented.");
+
+ return *this;
+}
+
+//
+// private methods
+//
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::UpdateCurrentPadValues(const MPad& pad)
+{
+// Updates current pad values.
+// ---
+
+ fIx = pad.GetIndices().GetFirst();
+ fIy = pad.GetIndices().GetSecond();
+ fX = pad.Position().X() * fgkLengthUnit;
+ fY = pad.Position().Y() * fgkLengthUnit;
+ fSector = fPlaneSegmentation->Zone(pad);
+}
+
+//
+// public methods
+//
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::SetPadSize(Float_t p1, Float_t p2)
+{
+// Set pad size Dx*Dy
+// ---
+
+ Fatal("SetPadSize", "Not uniform pad size.");
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::SetDAnod(Float_t d)
+{
+// Set anod pitch
+// ---
+
+ fWireD = d;
+}
+
+//______________________________________________________________________________
+Float_t AliMUONSt1Segmentation::GetAnod(Float_t xhit) const
+{
+// Anod wire coordinate closest to xhit
+// Returns for a hit position xhit the position of the nearest anode wire
+// From AliMUONSegmentationV01.
+// ---
+
+ Float_t wire= (xhit>0) ? Int_t(xhit/fWireD) + 0.5
+ : Int_t(xhit/fWireD) - 0.5;
+ return fWireD*wire;
+
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::GetPadI(Float_t x, Float_t y, Float_t z,
+ Int_t& ix, Int_t& iy)
+{
+// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
+// ---
+
+ GetPadI(x, y, ix, iy);
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::GetPadI(Float_t x, Float_t y,
+ Int_t& ix, Int_t& iy)
+{
+// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
+// If there is no pad, ix = 0, iy = 0 are returned.
+// ---
+
+ MPad pad = fPlaneSegmentation
+ ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), false);
+
+ ix = pad.GetIndices().GetFirst();
+ iy = pad.GetIndices().GetSecond();
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::GetPadC(Int_t ix, Int_t iy,
+ Float_t& x, Float_t& y, Float_t& z)
+{
+// Transform from pad to real coordinates
+// ---
+
+ z = fZ;
+ GetPadC(ix, iy, x , y);
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::GetPadC(Int_t ix, Int_t iy,
+ Float_t& x, Float_t& y)
+{
+// Transform from pad to real coordinates
+// If there is no pad, x = 0., y = 0. are returned.
+// ---
+
+ MPad pad = fPlaneSegmentation->PadByIndices(MIntPair(ix,iy));
+
+ x = pad.Position().X() * fgkLengthUnit;
+ y = pad.Position().Y() * fgkLengthUnit;
+}
+
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::Init(Int_t chamber)
+{
+// Initialize segmentation
+// ---
+
+ // find Npx, Npy and save this info
+
+ // reference to chamber
+ AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
+ fChamber = &(pMUON->Chamber(chamber));
+ fRmin=fChamber->RInner();
+ fRmax=fChamber->ROuter();
+ fZ = fChamber->Z();
+ fId=chamber;
+}
+
+//______________________________________________________________________________
+Float_t AliMUONSt1Segmentation::Dpx() const
+{
+// Get pad size in x
+// ---
+
+ Fatal("Dpx", "Not uniform pad size.");
+ return 0.;
+}
+
+//______________________________________________________________________________
+Float_t AliMUONSt1Segmentation::Dpy() const
+{
+// Get pad size in y
+// ---
+
+ Fatal("Dpy", "Not uniform pad size.");
+ return 0.;
+}
+
+//______________________________________________________________________________
+Float_t AliMUONSt1Segmentation::Dpx(Int_t isector) const
+{
+// Pad size in x by sector
+// ---
+
+ return fPlaneSegmentation->PadDimensions(isector).X()*2.*fgkLengthUnit;
+}
+
+//______________________________________________________________________________
+Float_t AliMUONSt1Segmentation::Dpy(Int_t isector) const
+{
+// Pad size in x, y by Sector
+// ---
+
+ return fPlaneSegmentation->PadDimensions(isector).Y()*2.*fgkLengthUnit;
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::Npx() const
+{
+// Maximum number of Pads in x
+// ---
+
+ //Fatal("Npx", "Not yet implemented.");
+ return 142; //hard coded for the time being
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::Npy() const
+{
+// Maximum number of Pads in y
+// ---
+
+ //Fatal("Npy", "Not yet implemented.");
+ return 213; //hard coded for the time being
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::SetPad(Int_t ix, Int_t iy)
+{
+// Set pad position.
+// Sets virtual pad coordinates, needed for evaluating pad response
+// outside the tracking program.
+// From AliMUONSegmentationV01.
+// ---
+
+ GetPadC(ix, iy, fX, fY);
+ fSector = Sector(ix, iy);
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::SetHit(Float_t xhit, Float_t yhit, Float_t zhit)
+{
+// Set hit position
+// Sets virtual hit position, needed for evaluating pad response
+// outside the tracking program
+// From AliMUONSegmentationV01.
+
+ fXhit = xhit;
+ fYhit = yhit;
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t zhit,
+ Float_t dx, Float_t dy)
+{
+// Iterate over pads - initialiser
+// ---
+
+ // Sets the current pad to that located in the hit position
+
+ SetHit(GetAnod(xhit), yhit, 0.);
+
+ // Enable iterating in one dimension
+ if (dx == 0.) dx = 0.01;
+ if (dy == 0.) dy = 0.01;
+
+ fPlaneIterator
+ = fPlaneSegmentation
+ ->CreateIterator(MArea(TVector2(fXhit/fgkLengthUnit, fYhit/fgkLengthUnit),
+ TVector2(dx/fgkLengthUnit, dy/fgkLengthUnit)));
+
+ fPlaneIterator->First();
+
+ if (! fPlaneIterator->IsDone())
+ UpdateCurrentPadValues(fPlaneIterator->CurrentItem());
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::NextPad()
+{
+// Iterate over pads - stepper
+// ---
+
+ fPlaneIterator->Next();
+
+ if (! fPlaneIterator->IsDone())
+ UpdateCurrentPadValues(fPlaneIterator->CurrentItem());
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::MorePads()
+{
+// Iterate over pads - condition
+// ---
+
+ if (fPlaneIterator->IsDone())
+ return 0;
+ else
+ return 1;
+}
+
+//______________________________________________________________________________
+Float_t AliMUONSt1Segmentation::Distance2AndOffset(Int_t iX, Int_t iY,
+ Float_t x, Float_t y, Int_t* dummy)
+{
+// Returns the square of the distance between 1 pad
+// labelled by its channel numbers and a coordinate
+// ---
+
+ MPad pad = fPlaneSegmentation->PadByIndices(MIntPair(iX, iY));
+
+ if (!pad.IsValid())
+ Fatal("Distance2AndOffset", "Cannot locate pad.");
+
+ return (pad.Position()*fgkLengthUnit - TVector2(x, y)).Mod2();
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::GetNParallelAndOffset(Int_t iX, Int_t iY,
+ Int_t* Nparallel, Int_t* Offset)
+{
+// Number of pads read in parallel and offset to add to x
+// (specific to LYON, but mandatory for display)
+// ---
+
+ Fatal("GetNParallelAndOffset", "Not yet implemented.");
+}
+
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::Neighbours(Int_t iX, Int_t iY,
+ Int_t* Nlist,
+ Int_t Xlist[10], Int_t Ylist[10])
+{
+// Get next neighbours
+// ---
+
+ MPad pad = fPlaneSegmentation->PadByIndices(MIntPair(iX,iY));
+ Int_t &i = *Nlist;
+ i=0;
+ MVPadIterator* iter
+ = fPlaneSegmentation
+ ->CreateIterator(MArea(pad.Position(),2.*pad.Dimensions()*1.1));
+
+ for( iter->First(); !iter->IsDone() && i<10; iter->Next()) {
+ Xlist[i] = iter->CurrentItem().GetIndices().GetFirst();
+ Ylist[i] = iter->CurrentItem().GetIndices().GetSecond();
+ i++;
+ }
+
+ delete iter;
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::Ix()
+{
+// Current pad cursor during disintegration
+// x, y-coordinate
+// ---
+
+ return fPlaneIterator->CurrentItem().GetIndices().GetFirst();
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::Iy()
+{
+// Current pad cursor during disintegration
+// x, y-coordinate
+// ---
+
+ return fPlaneIterator->CurrentItem().GetIndices().GetSecond();
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::ISector()
+{
+// Current sector
+// ---
+
+ return fSector;
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::Sector(Int_t ix, Int_t iy)
+{
+// Calculate sector from pad coordinates
+// ---
+
+ return fPlaneSegmentation
+ ->Zone(fPlaneSegmentation->PadByIndices(MIntPair(ix, iy)));
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::Sector(Float_t x, Float_t y)
+{
+// Calculate sector from pad coordinates
+// ---
+
+ return fPlaneSegmentation
+ ->Zone(fPlaneSegmentation
+ ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit)));
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
+ Float_t& y1, Float_t& y2)
+{
+// Current integration limits
+// ---
+
+ x1 = fXhit - fX - Dpx(fSector)/2.;
+ x2 = x1 + Dpx(fSector);
+
+ y1 = fYhit - fY - Dpy(fSector)/2.;
+ y2 = y1 + Dpy(fSector);
+}
+
+//______________________________________________________________________________
+Int_t AliMUONSt1Segmentation::SigGenCond(Float_t x, Float_t y, Float_t z)
+{
+// Signal Generation Condition during Stepping
+// 0: don't generate signal
+// 1: generate signal
+// Comments:
+//
+// Crossing of pad boundary and mid plane between neighbouring wires is checked.
+// To correctly simulate the dependence of the spatial resolution on the angle
+// of incidence signal must be generated for constant steps on
+// the projection of the trajectory along the anode wire.
+//
+// Signal will be generated if particle crosses pad boundary or
+// boundary between two wires.
+//
+// From AliMUONSegmentationV01
+// ---
+
+ Int_t ixt, iyt;
+ GetPadI(x, y, ixt, iyt);
+ Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1;
+
+ if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::SigGenInit(Float_t x, Float_t y, Float_t z)
+{
+// Initialise signal generation at coord (x,y,z)
+// Initialises pad and wire position during stepping.
+// From AliMUONSegmentationV01
+// ---
+
+ fXt = x;
+ fYt = y;
+ GetPadI(x, y, fIxt, fIyt);
+ fIwt = (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ;
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const
+{
+// Test points for auto calibration
+// Returns test point on the pad plane.
+// Used during determination of the segmoid correction of the COG-method
+// From AliMUONSegmentationV01
+// ---
+
+ n=1;
+ x[0] = (fRmax+fRmin)/2/TMath::Sqrt(2.);
+ y[0] = x[0];
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::Draw(const char *opt) const
+{
+// Draw the segmentation zones.
+// (Called from AliMUON::BuildGeometry)
+// ---
+
+ Warning("Draw", "Not yet implemented.");
+}
+
+//______________________________________________________________________________
+void AliMUONSt1Segmentation::SetCorrFunc(Int_t isec, TF1* func)
+{
+// Set the correction function.
+// From AliMUONSegmentationV01
+// ---
+
+ fCorrA->AddAt(func, isec);
+}
+
+//______________________________________________________________________________
+TF1* AliMUONSt1Segmentation::CorrFunc(Int_t isec) const
+{
+// Get the correction Function.
+// From AliMUONSegmentationV01
+// ---
+
+ return (TF1*) fCorrA->At(isec);
+}
+
--- /dev/null
+#ifndef ALI_MUON_ST1_SEGMENTATION_H
+#define ALI_MUON_ST1_SEGMENTATION_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1Segmentation
+// -----------------------------
+// Segmentation for MUON station 1 using the external
+// mapping package
+
+#include <MPad.h>
+#include <MPlaneType.h>
+
+#include "AliSegmentation.h"
+
+class TObjArray;
+
+class MPlane;
+class MPlaneSegmentation;
+class MVPadIterator;
+
+class AliMUONChamber;
+
+class AliMUONSt1Segmentation : public AliSegmentation
+{
+ public:
+ AliMUONSt1Segmentation(const MPlaneType planeType);
+ AliMUONSt1Segmentation(const AliMUONSt1Segmentation& rhs);
+ AliMUONSt1Segmentation();
+
+ virtual ~AliMUONSt1Segmentation();
+
+ //
+ // methods derived from base class
+ //
+
+ // Set Chamber Segmentation Parameters
+ //
+ virtual void SetPadSize(Float_t p1, Float_t p2);
+ // Pad size Dx*Dy
+ virtual void SetDAnod(Float_t D);
+ // Anode Pitch
+
+ // Transform from pad (wire) to real coordinates and vice versa
+ //
+ virtual Float_t GetAnod(Float_t xhit) const;
+ // Anode wire coordinate closest to xhit
+ virtual void GetPadI(Float_t x, Float_t y, Float_t z, Int_t& ix, Int_t& iy);
+ virtual void GetPadI(Float_t x, Float_t y , Int_t &ix, Int_t &iy) ;
+ // Transform from pad to real coordinates
+ virtual void GetPadC(Int_t ix, Int_t iy, Float_t& x, Float_t& y, Float_t& z);
+ virtual void GetPadC(Int_t ix, Int_t iy, Float_t& x, Float_t& y);
+ // Transform from real to pad coordinates
+
+
+ // Initialisation
+ //
+ virtual void Init(Int_t chamber);
+
+ // Get member data
+ //
+ virtual Float_t Dpx() const;
+ virtual Float_t Dpy() const;
+ // Pad size in x, y
+ virtual Float_t Dpx(Int_t) const;
+ virtual Float_t Dpy(Int_t) const;
+ // Pad size in x, y by Sector
+ virtual Int_t Npx() const;
+ virtual Int_t Npy() const;
+ // Maximum number of Pads in y
+
+ virtual void SetPad(Int_t, Int_t);
+ // Set pad position
+ virtual void SetHit(Float_t, Float_t, Float_t);
+ // Set hit position
+
+ // Iterate over pads
+ //
+ virtual void FirstPad(Float_t xhit, Float_t yhit, Float_t zhit,
+ Float_t dx, Float_t dy);
+ virtual void NextPad();
+ virtual Int_t MorePads();
+
+ virtual Float_t Distance2AndOffset(Int_t iX, Int_t iY,
+ Float_t X, Float_t Y, Int_t* dummy) ;
+ // Distance between 1 pad and a position
+ virtual void GetNParallelAndOffset(Int_t iX, Int_t iY,
+ Int_t* Nparallel, Int_t* Offset);
+ // Number of pads read in parallel and offset to add to x
+ // (specific to LYON, but mandatory for display)
+ virtual void Neighbours(Int_t iX, Int_t iY,
+ Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]);
+ // Get next neighbours
+
+ // Current values
+ //
+ virtual Int_t Ix();
+ virtual Int_t Iy();
+ // Current pad cursor during disintegration
+ // x, y-coordinate
+ virtual Int_t ISector();
+ // current sector
+
+ virtual Int_t Sector(Int_t ix, Int_t iy);
+ virtual Int_t Sector(Float_t x, Float_t y);
+ // calculate sector from pad coordinates
+
+ virtual void IntegrationLimits(Float_t& x1, Float_t& x2,
+ Float_t& y1, Float_t& y2);
+ // Current integration limits
+
+ // Signal Generation
+ //
+ virtual Int_t SigGenCond(Float_t x, Float_t y, Float_t z);
+ // Signal Generation Condition during Stepping
+ virtual void SigGenInit(Float_t x, Float_t y, Float_t z);
+ // Initialise signal generation at coord (x,y,z)
+
+
+ virtual void GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const;
+ // Test points for auto calibration
+ virtual void Draw(const char *opt = "") const;
+ // Draw the segmentation zones
+
+ // Function for systematic corrections
+ //
+ virtual void SetCorrFunc(Int_t, TF1*);
+ // Set the correction function
+ virtual TF1* CorrFunc(Int_t) const;
+ // Get the correction Function
+
+ private:
+ // operators
+ AliMUONSt1Segmentation& operator=(const AliMUONSt1Segmentation & rhs);
+
+ // methods
+ void UpdateCurrentPadValues(const MPad& pad);
+
+ // constants
+ static const Float_t fgkWireD; // default wire pitch
+ static const Float_t fgkLengthUnit;// conversion between length units
+ // from mapping (mm) to AliRoot (cm)
+
+ // data members
+
+ // From mapping
+ //
+ MPlane* fPlane; // plane (from mapping)
+ MPlaneSegmentation* fPlaneSegmentation;// plane segmantation (from mapping)
+ MVPadIterator* fPlaneIterator; // ! iterator over pads
+
+ // Wire pitch
+ //
+ Float_t fWireD; // wire pitch
+ // (smaller distance between anode wires)
+
+ // Reference to mother chamber
+ //
+ AliMUONChamber* fChamber; // ! Reference to mother chamber
+ Int_t fId; // Identifier
+ Float_t fRmin; // inner radius
+ Float_t fRmax; // outer radius
+ Float_t fZ; // z-position of chamber
+
+ // Current pad during integration (cursor for disintegration)
+ //
+ Int_t fIx; // ! pad coord. x
+ Int_t fIy; // ! pad coord. y
+ Float_t fX; // ! real coord. x
+ Float_t fY; // ! real ccord. y
+ Int_t fSector; // ! Current sector
+
+ // Current pad and wire during tracking (cursor at hit centre)
+ //
+ Float_t fXhit; // ! x-position of hit
+ Float_t fYhit; // ! y-position of hit
+
+ // Reference point to define signal generation condition
+ //
+ Int_t fIxt; // ! pad coord. x
+ Int_t fIyt; // ! pad coord. y
+ Int_t fIwt; // ! wire number
+ Float_t fXt; // ! x
+ Float_t fYt; // ! y
+
+ TObjArray* fCorrA; // ! Array of correction functions
+
+ ClassDef(AliMUONSt1Segmentation,1) // Station1 segmentation
+};
+
+#endif //ALI_MUON_ST1_SEGMENTATION_H
+
+
+
+
+
+
+
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1SpecialMotif
+// ----------------------------
+// Encapsulate the distance between the center of a given daughter card
+// and the pad/kapton connector.
+
+#include "AliMUONSt1SpecialMotif.h"
+
+//__________________________________________________________________________
+AliMUONSt1SpecialMotif::AliMUONSt1SpecialMotif(const TVector2& delta,
+ Double_t rotAngle)
+ :fDelta(delta),
+ fRotAngle(rotAngle)
+{
+// normal constructor
+}
+
+//__________________________________________________________________________
+AliMUONSt1SpecialMotif::AliMUONSt1SpecialMotif()
+ :fDelta(TVector2(0.,0.)),
+ fRotAngle(0.)
+{
+// default constructor
+}
+
+//__________________________________________________________________________
+AliMUONSt1SpecialMotif::AliMUONSt1SpecialMotif(const AliMUONSt1SpecialMotif& src)
+ :fDelta(src.fDelta),
+ fRotAngle(src.fRotAngle)
+
+{
+// copy constructor
+}
+
+//__________________________________________________________________________
+AliMUONSt1SpecialMotif::~AliMUONSt1SpecialMotif()
+{
+// destructor
+}
+
--- /dev/null
+#ifndef ALI_MUON_ST1_SPECIAL_MOTIF_H
+#define ALI_MUON_ST1_SPECIAL_MOTIF_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONSt1SpecialMotif
+// ----------------------------
+// Encapsulate the distance between the center of a given daughter card
+// and the pad/kapton connector.
+
+#include <TVector2.h>
+
+class AliMUONSt1SpecialMotif
+{
+ public:
+ AliMUONSt1SpecialMotif();
+ AliMUONSt1SpecialMotif(const TVector2& delta,Double_t rotAngle=0.);
+ AliMUONSt1SpecialMotif(const AliMUONSt1SpecialMotif& src);
+ virtual ~AliMUONSt1SpecialMotif();
+
+ TVector2 GetDelta() const {return fDelta;}
+ Double_t GetRotAngle() const {return fRotAngle;}
+
+ private:
+ TVector2 fDelta; // offset of this motif
+ Double_t fRotAngle;// rotation angle in degrees (0° = vertical)
+};
+
+#endif //ALI_MUON_ST1_SPECIAL_MOTIF_H
/*
$Log$
+Revision 1.25 2003/01/14 10:50:19 alibrary
+Cleanup of STEER coding conventions
+
Revision 1.24 2002/11/21 17:01:56 alibrary
Removing AliMCProcess and AliMC
: AliMUON(name,title)
{
// Constructor
- AliMUONFactory::Build(this, "default");
+ AliMUONFactory factory;
+ factory.Build(this, title);
}
void AliMUONv0::CreateGeometry()
/*
$Log$
+Revision 1.39 2003/01/14 10:50:19 alibrary
+Cleanup of STEER coding conventions
+
Revision 1.38 2002/11/21 17:01:56 alibrary
Removing AliMCProcess and AliMC
{
// Constructor
fChambers = 0;
+ fStations = 0;
}
//___________________________________________
: AliMUON(name,title)
{
// Constructor
- AliMUONFactory::Build(this, title);
+ // By default include all stations
+ fStations = new Int_t[5];
+ for (Int_t i=0; i<5; i++) fStations[i] = 1;
+
+ AliMUONFactory factory;
+ factory.Build(this, title);
}
//___________________________________________
AliMUONChamber *iChamber, *iChamber1, *iChamber2;
- Int_t stations[5] = {1, 1, 1, 1, 1};
-
- if (stations[0]) {
+
+ if (fStations[0]) {
//********************************************************************
// Station 1 **
// idrotm[1101],"ONLY");
// }
}
- if (stations[1]) {
+ if (fStations[1]) {
//********************************************************************
// Station 2 **
Float_t xxmax = (bFrameLength - nulocLength)/2.;
Int_t index=0;
- if (stations[2]) {
+ if (fStations[2]) {
//********************************************************************
// Station 3 **
}
}
- if (stations[3]) {
+ if (fStations[3]) {
//********************************************************************
// Station 4 **
}
- if (stations[4]) {
+ if (fStations[4]) {
//********************************************************************
virtual void Init();
virtual Int_t IsVersion() const {return 1;}
virtual void StepManager();
+protected:
+ Int_t* fStations; //! allow to externally set which station to create
private:
ClassDef(AliMUONv1,1) // MUON Detector class Version 1
};
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONv2
+// ---------------
+// Inherits from AliMUONv1 but with a more detailed
+// geometrical description of station 1
+
+#include <algorithm>
+#include <vector>
+
+#include <string.h>
+
+#include <TVector2.h>
+#include <TClonesArray.h>
+#include <TLorentzVector.h>
+
+
+#include "AliMUONv2.h"
+#include "AliMUONConstants.h"
+#include "AliMUONHit.h"
+#include "AliRun.h"
+#include "AliMagF.h"
+#include "AliConst.h"
+
+#include <MReader.h>
+#include <MSector.h>
+#include <MRow.h>
+#include <MVRowSegment.h>
+#include <MVMotif.h>
+#include <MMotifMap.h>
+#include <MMotifPosition.h>
+#include <MMotifType.h>
+#include <MIntPair.h>
+
+
+#include <Riostream.h>
+
+ClassImp(AliMUONv2)
+
+
+
+const GReal_t AliMUONv2::fgkHzPadPlane=0.0148/2.; //Pad plane
+const GReal_t AliMUONv2::fgkHzFoam = 2.083/2.; // Foam of mechanicalplane
+const GReal_t AliMUONv2::fgkHzFR4 = 0.0031/2.; // FR4 of mechanical plane
+const GReal_t AliMUONv2::fgkHzSnPb = 0.0091/2.; //Pad/Kapton connection (66 pt)
+const GReal_t AliMUONv2::fgkHzKapton = 0.0122/2.; //Kapton
+const GReal_t AliMUONv2::fgkHzBergPlastic = 0.3062/2.; //Berg connector
+const GReal_t AliMUONv2::fgkHzBergCopper = 0.1882/2.; //Berg connector
+const GReal_t AliMUONv2::fgkHzDaughter = 0.0156/2.; //Daughter board
+const GReal_t AliMUONv2::fgkHzGas = 0.2/2.; //Gas
+const GReal_t AliMUONv2::fgkHxQuadrant = 94.69/2.; //Box surrounding quadrant
+const GReal_t AliMUONv2::fgkHyQuadrant = 100.31/2.; //Box surrounding quadrant
+const GReal_t AliMUONv2::fgkMotherIR = 18.3;
+const GReal_t AliMUONv2::fgkMotherOR = 104.974;
+const GReal_t AliMUONv2::fgkMotherThick = 6.5/2; //6.5cm between two quadrants
+const GReal_t AliMUONv2::fgkMotherPhiL = 0.;
+const GReal_t AliMUONv2::fgkMotherPhiU = 90.;
+
+
+const GReal_t AliMUONv2::fgkHxHole=1.5/2.;
+const GReal_t AliMUONv2::fgkHyHole=6./2.;
+const GReal_t AliMUONv2::fgkHxBergPlastic=0.74/2.;
+const GReal_t AliMUONv2::fgkHyBergPlastic=5.09/2.;
+const GReal_t AliMUONv2::fgkHxBergCopper=0.25/2.;
+const GReal_t AliMUONv2::fgkHyBergCopper=3.6/2.;
+const GReal_t AliMUONv2::fgkHxKapton=0.8/2.;
+const GReal_t AliMUONv2::fgkHyKapton=5.7/2.;
+const GReal_t AliMUONv2::fgkHxDaughter=2.3/2.;
+const GReal_t AliMUONv2::fgkHyDaughter=6.3/2.;
+const GReal_t AliMUONv2::fgkOffsetX=1.46;
+const GReal_t AliMUONv2::fgkOffsetY=0.71;
+const GReal_t AliMUONv2::fgkDeltaFilleEtamX=0.;
+const GReal_t AliMUONv2::fgkDeltaFilleEtamY=0.5;
+
+const char* AliMUONv2::fgkHoleName="MCHL";
+const char* AliMUONv2::fgkDaughterName="MCDB";
+const char AliMUONv2::fgkFoamLayerSuffix='F';
+const char* AliMUONv2::fgkQuadrantName="QUA";
+
+//___________________________________________
+AliMUONv2::AliMUONv2()
+ : AliMUONv1(),
+ fIdSens(0)
+{
+// Default Constructor
+//
+
+ // keep secondaries
+ SetIshunt(0);
+}
+
+//___________________________________________
+AliMUONv2::AliMUONv2(const char *name, const char *title)
+ : AliMUONv1(name,title),
+ fIdSens(0)
+{
+ // keep secondaries
+ SetIshunt(0);
+
+ // create hits array
+ fHits = new TClonesArray("AliMUONHit",1000);
+ gAlice->AddHitList(fHits);
+}
+
+//___________________________________________
+AliMUONv2::AliMUONv2(const AliMUONv2& rMUON)
+{
+// Dummy copy constructor
+}
+
+//___________________________________________
+AliMUONv2::~AliMUONv2()
+{
+// Destructor
+ if(fDebug) printf("%s: Calling AliMUONv2 destructor !!!\n",ClassName());
+
+ if (fHits) {
+ fHits->Delete();
+ delete fHits;
+ }
+}
+
+//___________________________________________
+void AliMUONv2::CreateGeometry()
+{
+// Create the GEANT geometry for the dimuon arm.
+// Use the parent's method for stations 2, 3, 4 and 5.
+// Use the detailed code for the first station.
+// --
+ cout << "AliMUONv2::CreateGeometry()" << endl;
+ cout << "_________________________________________" << endl;
+
+ // tracking medias
+ Int_t* idtmed = fIdtmed->GetArray()-1099;
+ Int_t idAir = idtmed[1100]; // medium 1
+
+
+
+ //create reflexion matrix
+ Int_t reflXZ,reflYZ,reflXY;
+ AliMatrix(reflXZ, 90., 180., 90., 90., 180., 0.);
+ AliMatrix(reflYZ, 90., 0., 90.,-90., 180., 0.);
+ AliMatrix(reflXY, 90., 180., 90., 270., 0., 0.);
+
+ CreateHole();
+ CreateDaughterBoard();
+
+ //build the quadrant
+ CreateQuadrant(1);
+ CreateQuadrant(2);
+ GReal_t par[5];
+ par[0] = fgkMotherIR;
+ par[1] = fgkMotherOR;
+ par[2] = fgkHzGas;
+ par[3] = fgkMotherPhiL;
+ par[4] = fgkMotherPhiU;
+
+ gMC->Gsvolu("S01G","TUBS",idAir,par,5);
+ gMC->Gspos("S01G",1,QuadrantName(1),0,0,0,0,"ONLY");
+ gMC->Gsvolu("S02G","TUBS",idAir,par,5);
+ gMC->Gspos("S02G",1,QuadrantName(2),0,0,0,0,"ONLY");
+
+ // place the four copies of it
+
+ //parameters
+ TVector3 pos[4];
+ Int_t rotm[4];
+
+ Double_t deltaZ = 6.5/2.;
+ pos[0]=TVector3(-2.6,-2.6,AliMUONConstants::DefaultChamberZ(0)+deltaZ);
+ rotm[0]=0;
+ pos[1]=TVector3(2.6,-2.6,AliMUONConstants::DefaultChamberZ(0)-deltaZ);
+ rotm[1]=reflXZ;
+ pos[2]=TVector3(2.6,2.6,AliMUONConstants::DefaultChamberZ(0)+deltaZ);
+ rotm[2]=reflXY;
+ pos[3]=TVector3(-2.6,2.6,AliMUONConstants::DefaultChamberZ(0)-deltaZ);
+ rotm[3]=reflYZ;
+
+ //placing
+ GReal_t posX,posY,posZ;
+ for (Int_t i=0;i<4;i++){
+ posX=pos[i].X();
+ posY=pos[i].Y();
+ // the 1st chamber
+ posZ=pos[i].Z();
+ gMC->Gspos(QuadrantName(1),i+1,"ALIC",posX,posY,posZ,rotm[i],"ONLY");
+ // the 2nd chamber
+ posZ=pos[i].Z()+AliMUONConstants::DefaultChamberZ(1)
+ -AliMUONConstants::DefaultChamberZ(0);
+ gMC->Gspos(QuadrantName(2),i+5,"ALIC",posX,posY,posZ,rotm[i],"ONLY");
+ }
+ static Int_t stations[5]={0,1,1,1,1};
+ fStations=stations;
+ AliMUONv1::CreateGeometry();
+}
+//___________________________________________
+void AliMUONv2::CreateQuadrant(Int_t chamber)
+{
+// create the quadrant (bending and non-bending planes)
+// for the given chamber
+// --
+ CreateFrame(chamber);
+
+ TSpecialMap specialMap;
+
+ TVector3 where;
+ specialMap[1001] = AliMUONSt1SpecialMotif(TVector2(0.1 ,0.84),90.);
+ specialMap[1002] = AliMUONSt1SpecialMotif(TVector2(0.5 ,0.76));
+ specialMap[1003] = AliMUONSt1SpecialMotif(TVector2(1.01,0.76));
+ MReader reader1(kBendingPlane);
+ MSector* sector1 = reader1.BuildSector();
+ where=TVector3(0.185+2.6,-0.52+2.6,totalHz()+fgkHzGas);
+ PlaceSector(sector1,specialMap,where,chamber);
+
+
+ specialMap.clear();
+ specialMap[4001] = AliMUONSt1SpecialMotif(TVector2(1.01,0.59),90.);
+ specialMap[4002] = AliMUONSt1SpecialMotif(TVector2(1.96, 0.17));
+ specialMap[4003] = AliMUONSt1SpecialMotif(TVector2(1.61,-1.18));
+ specialMap[4004] = AliMUONSt1SpecialMotif(TVector2(0.2 ,-0.08));
+ specialMap[4005] = AliMUONSt1SpecialMotif(TVector2(0.2 , 0.25));
+ specialMap[4006] = AliMUONSt1SpecialMotif(TVector2(0.28, 0.21));
+
+ MReader reader2(kNonBendingPlane);
+ MSector* sector2 = reader2.BuildSector();
+ where=TVector3(-0.13+2.6,-0.1775+2.6,-totalHz()-fgkHzGas);
+ PlaceSector(sector2,specialMap,where,chamber);
+}
+
+//___________________________________________
+void AliMUONv2::CreateMaterials()
+{
+// --- Define the various mixtures for GEANT ---
+
+ // Ar-CO2 gas (80%+20%)
+ Float_t ag1[2] = { 39.95,44.01};
+ Float_t zg1[2] = { 18.,22.};
+ Float_t dg1 = .001821;
+ Float_t wg1[2] = { .8,0.2};
+ // use wg1 weighting factors (6th arg > 0)
+ AliMixture(22, "ArCO2 80%$", ag1, zg1, dg1, 2, wg1);
+
+ // Ar-buthane-freon gas -- trigger chambers
+ Float_t atr1[4] = { 39.95,12.01,1.01,19. };
+ Float_t ztr1[4] = { 18.,6.,1.,9. };
+ Float_t wtr1[4] = { .56,.1262857,.2857143,.028 };
+ Float_t dtr1 = .002599;
+ AliMixture(23, "Ar-freon $", atr1, ztr1, dtr1, 4, wtr1);
+
+ // Rohacell 51 - imide methacrylique
+ Float_t aRohacell51[4] = {12.01,1.01,16.00,14.01};
+ Float_t zRohacell51[4] = {6.,1.,8.,7.};
+ Float_t dRohacell51 = 0.052;
+ Float_t wRohacell51[4] = {9.,13.,2.,1.};
+ // use relative A (molecular) values (6th arg < 0)
+ AliMixture(32, "FOAM$",aRohacell51,zRohacell51,dRohacell51,-4,wRohacell51);
+
+ Float_t aSnPb[2] = {118.69,207.19};
+ Float_t zSnPb[2] = {50,82};
+ Float_t dSnPb = 8.926;
+ Float_t wSnPb[2] = {0.6, 0.4} ;
+ // use wSnPb weighting factors (6th arg > 0)
+ AliMixture(35, "SnPb$", aSnPb,zSnPb,dSnPb,2,wSnPb);
+
+ // plastic definition from K5, Freiburg (found on web)
+ Float_t aPlastic[2]={1.01,12.01};
+ Float_t zPlastic[2]={1,6};
+ Float_t denPlastic=1.107;
+ Float_t wPlastic[2]={1,1};
+ // use relative A (molecular) values (6th arg < 0)...no other info...
+ AliMixture( 33, "Plastic$",aPlastic,zPlastic,denPlastic,-2,wPlastic);
+
+ // from CERN note NUFACT Note023, Oct.2000
+ // Inox/Stainless Steel (18%Cr, 9%Ni)
+ Float_t aInox[3] = {55.847,51.9961,58.6934};
+ Float_t zInox[3] = {26.,24.,28.};
+ Float_t denInox = 7.930;
+ Float_t wInox[3] = {0.73,0.18,0.09};
+ // use wInox weighting factors (6th arg > 0)
+ AliMixture(37, "StainlessSteel$",aInox,zInox,denInox,3,wInox);
+
+ // bakelite
+ Float_t abak[3] = {12.01 , 1.01 , 16.};
+ Float_t zbak[3] = {6. , 1. , 8.};
+ Float_t wbak[3] = {6. , 6. , 1.};
+ Float_t dbak = 1.4;
+ AliMixture(19, "Bakelite$", abak, zbak, dbak, -3, wbak);
+
+ // Ar-Isobutane gas (80%+20%)
+ Float_t ag[3] = { 39.95,12.01,1.01 };
+ Float_t zg[3] = { 18.,6.,1. };
+ Float_t wg[3] = { .8,.057,.143 };
+ Float_t dg = .0019596;
+ AliMixture(20, "ArC4H10 GAS$", ag, zg, dg, 3, wg);
+
+ // Ar-Isobutane-Forane-SF6 gas (49%+7%+40%+4%) -- trigger
+ Float_t atrig[5] = { 39.95,12.01,1.01,19.,32.066 };
+ Float_t ztrig[5] = { 18.,6.,1.,9.,16. };
+ Float_t wtrig[5] = { .49,1.08,1.5,1.84,0.04 };
+ Float_t dtrig = .0031463;
+ AliMixture(21, "TRIG GAS$", atrig, ztrig, dtrig, -5, wtrig);
+
+ // Ar-CO2 gas
+ Float_t agas[3] = { 39.95,12.01,16. };
+ Float_t zgas[3] = { 18.,6.,8. };
+ Float_t wgas[3] = { .74,.086684,.173316 };
+ Float_t dgas = .0018327;
+ AliMixture(24, "ArCO2 GAS$", agas, zgas, dgas, 3, wgas);
+
+// --- Define the various AliMaterials for GEANT ---
+ // from PDG and "The Particle Detector BriefBook", Bock and Vasilescu, P.18
+ AliMaterial( 9, "Aluminium$", 26.98, 13., 2.7, -8.9, 26.1);
+ AliMaterial(10, "Aluminium$", 26.98, 13., 2.7, -8.9, 26.1);
+ AliMaterial(15, "air$", 14.61, 7.3, .001205, -30423.24, 67500);
+ AliMaterial(30, "Copper$", 63.546,29.,8.96,-1.43,9.6);
+ AliMaterial(31, "FR4$", 17.749, 8.875, 1.7, -19.4, 999.); // from DPG
+ AliMaterial(34, "Kapton$", 12.01,6,1.42,-28.6,999); // from DPG
+ // Density of FrameEpoxy only from manufacturer's specifications
+ // Frame composite epoxy , X0 in g/cm**2 (guestimation!)
+ AliMaterial(36, "FrameEpoxy",12.24,6.0,1.85,-19.14,999);
+
+// --- Define the tracking medias (AliMediums) for GEANT ---
+ GReal_t epsil = .001; // Tracking precision,
+ GReal_t stemax = -1.; // Maximum displacement for multiple scat
+ GReal_t tmaxfd = -20.; // Maximum angle due to field deflection
+ GReal_t deemax = -.3; // Maximum fractional energy loss, DLS
+ GReal_t stmin = -.8;
+ GReal_t maxStepAlu = 0.001; // from AliMUON.cxx
+ GReal_t maxDestepAlu = -1.; // from AliMUON.cxx
+ GReal_t maxStepGas=0.01; // from AliMUON.cxx
+
+ Int_t iSXFLD = gAlice->Field()->Integ();
+ Float_t sXMGMX = gAlice->Field()->Max();
+
+ AliMedium(1, "AIR_CH_US$", 15, 1, iSXFLD, sXMGMX, tmaxfd,
+ stemax, deemax, epsil, stmin);
+ AliMedium(4, "ALU_CH_US$", 9, 0, iSXFLD, sXMGMX, tmaxfd,
+ maxStepAlu, maxDestepAlu, epsil, stmin);
+ AliMedium(5, "ALU_CH_US$", 10, 0, iSXFLD, sXMGMX, tmaxfd,
+ maxStepAlu,maxDestepAlu, epsil, stmin);
+ AliMedium(6, "AR_CH_US ", 20, 1, iSXFLD, sXMGMX,
+ tmaxfd, fMaxStepGas,fMaxDestepGas, epsil, stmin);
+
+ // Ar-Isobuthane-Forane-SF6 gas
+ AliMedium(7, "GAS_CH_TRIGGER ", 21, 1, iSXFLD, sXMGMX,
+ tmaxfd, stemax, deemax, epsil, stmin);
+ AliMedium(8, "BAKE_CH_TRIGGER ", 19, 0, iSXFLD, sXMGMX,
+ tmaxfd, fMaxStepAlu, fMaxDestepAlu, epsil, stmin);
+
+ AliMedium(9, "ARG_CO2$", 22, 1, iSXFLD, sXMGMX, tmaxfd, maxStepGas,
+ maxDestepAlu, epsil, stmin);
+ AliMedium(10, "COPPER_CH$", 30, 0, iSXFLD, sXMGMX, tmaxfd,
+ maxStepAlu, maxDestepAlu, epsil, stmin);
+ AliMedium(11, "PCB_COPPER ", 31, 0, iSXFLD, sXMGMX, tmaxfd,
+ fMaxStepAlu, fMaxDestepAlu, epsil, stmin);
+ AliMedium(12, "VETRONITE ", 32, 0, iSXFLD, sXMGMX, tmaxfd,
+ fMaxStepAlu, fMaxDestepAlu, epsil, stmin);
+ AliMedium(13, "CARBON ", 33, 0, iSXFLD, sXMGMX, tmaxfd,
+ fMaxStepAlu, fMaxDestepAlu, epsil, stmin);
+ AliMedium(14, "Rohacell ", 34, 0, iSXFLD, sXMGMX, tmaxfd,
+ fMaxStepAlu, fMaxDestepAlu, epsil, stmin);
+ AliMedium(15, "FR4_CH$", 31, 0,iSXFLD, sXMGMX, 10., .01,.1, .003, .003);
+ AliMedium(16, "FOAM_CH$", 32, 0,
+ iSXFLD, sXMGMX, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
+ AliMedium(17, "Plastic$", 33, 0,iSXFLD, sXMGMX, 10., .01, 1., .003, .003);
+ AliMedium(18, "Kapton$", 34, 0,iSXFLD, sXMGMX, 10., .01, 1., .003, .003);
+ AliMedium(19, "SnPb$", 35, 0,iSXFLD, sXMGMX, 10., .01, 1., .003, .003);
+ AliMedium(20, "FrameCH$", 36, 1,iSXFLD, sXMGMX, 10., .001, 0.001, .001, .001);
+ AliMedium(21, "InoxBolts$", 37,1,iSXFLD, sXMGMX, 10., .01, 1., .003, .003);
+}
+
+void AliMUONv2::CreateFrame(Int_t chamber)
+{
+// Create the non-sensitive elements of the frame for the <chamber>
+
+
+// Matrices
+ Int_t idrotm[1199];
+// To Be Checked....
+// Rotation matrices in the x-y plane
+// phi = -45 deg
+ AliMatrix(idrotm[1101], 90., 315., 90., 45., 0., 0.);
+// phi = -90 deg
+ AliMatrix(idrotm[1102], 90., 90., 90., 180., 0., 0.);
+// theta = +90 deg
+ AliMatrix(idrotm[1103], 180., 0., 90., 90.,90., 0.);
+
+// phi = +45 deg
+ AliMatrix(idrotm[1104], 90., 45., 90., 135., 0., 0.);
+// phi = +45 deg + rotation 180° around Y
+ AliMatrix(idrotm[1105], 90., 45., 90., 315., 180., 0.);
+
+// Translation matrices in the x-y plane
+// X -> X ; Y -> Y; Z -> Z
+ AliMatrix(idrotm[1110], 90., 0., 90., 90., 0., 0.);
+// X->-X; Y -> Y; Z -> -Z
+ AliMatrix(idrotm[1111], 90., 180., 90., 90., 180., 0.);
+// X->-X; Y ->-Y; Z -> Z
+ AliMatrix(idrotm[1112], 90., 180., 90., 270., 0., 0.);
+// X->X; Y ->-Y; Z -> -Z
+ AliMatrix(idrotm[1113], 90., 0., 90., 270., 180., 0.);
+//
+
+ // tracking medias
+ Int_t* idtmed = fIdtmed->GetArray()-1099;
+
+ Int_t idAir = idtmed[1100]; // medium 1
+ Int_t idSolder = idtmed[1118]; // medium 19
+ Int_t idFrameEpoxy = idtmed[1119]; // medium 20 = Frame Epoxy ME730
+ Int_t idInox = idtmed[1120]; // medium 21 Stainless Steel (18%Cr,9%Ni,Fe)
+
+//________________________________________________________________
+//
+// Original model:
+//
+// Epoxy Frame segments
+//
+// OutTopTrapFrame
+// ------------ |
+// OutEdgeTrapFrame / |
+// / | InVFrame
+// OutCornerTrapFrame / |
+// | --|
+// OutVFrame | _- InArcFrame
+// |___________|
+// InHFrame
+//
+//
+// DATE: 27 NOVEMBER 2002 - MODEL UPDATED. THE MOTHER VOLUME IS A TUBS.
+//__________________________________________________________________
+
+ const Float_t hzFrameThickness = 1.186/2.; //equivalent thickness
+ const Float_t hzOuterFrameEpoxy = 1.23/2.; //equivalent thickness
+ const Float_t hzOuterFrameSolder = 0.032/2.; //equivalent thickness
+ const Float_t hzOuterFrameInox = 0.035/2.; //equivalent thickness
+
+ // InHFrame parameters
+ const Float_t hxInHFrame = 75.8/2.;
+ const Float_t hyInHFrame = 2.5/2.;
+ const Float_t hzInHFrame = hzFrameThickness;
+
+ // InVFrame parameters
+ const Float_t hxInVFrame = 2.5/2.;
+ const Float_t hyInVFrame = 73.3/2.;
+ const Float_t hzInVFrame = hzFrameThickness;
+
+ //Flat 1mm vertical section
+ const Float_t hxV1mm = 0.1/2.;
+ const Float_t hyV1mm = 2.5/2.;
+ const Float_t hzV1mm = hzFrameThickness;
+
+ //Flat 1mm horizontal section
+ const Float_t hxH1mm = 2.5/2.;
+ const Float_t hyH1mm = 0.1/2.;
+ const Float_t hzH1mm = hzFrameThickness;
+
+ // InArcFrame parameters
+ const Float_t IAF = 15.70;
+ const Float_t OAF = 18.20;
+ const Float_t hzAF = hzFrameThickness;
+ const Float_t AFphi1 = 0.0;
+ const Float_t AFphi2 = 90.0;
+
+ // ScrewsInFrame parameters HEAD
+ const Float_t SCRUHMI = 0.;
+ const Float_t SCRUHMA = 0.690/2.;
+ const Float_t SCRUHLE = 0.4/2.;
+ // ScrewsInFrame parameters MIDDLE
+ const Float_t SCRUMMI = 0.;
+ const Float_t SCRUMMA = 0.39/2.;
+ const Float_t SCRUMLE = hzFrameThickness;
+ // ScrewsInFrame parameters NUT
+ const Float_t SCRUNMI = 0.;
+ const Float_t SCRUNMA = 0.78/2.;
+ const Float_t SCRUNLE = 0.8/2.;
+
+ // OutVFrame parameters
+ const Float_t hxOutVFrame = 2.5/2.;
+ const Float_t hyOutVFrame = 43.927/2.;
+ const Float_t hzOutVFrame = hzFrameThickness;
+
+///////////////////////////////////////////////////////
+
+// OutTopCuboidFrame Epoxy parameters
+ const Float_t hxOutHFrame = 31.9304/2.;
+ const Float_t hyOutHFrame = 8.4/2.;
+ const Float_t hzOutHFrame = hzOuterFrameEpoxy;
+
+// OutTopTrapFrameA Epoxy parameters
+ const Float_t hzOTTFA = hzOuterFrameEpoxy;
+ const Float_t tetOTTFA = 0.;
+ const Float_t phiOTTFA = 0.;
+ const Float_t h1OTTFA = 9.6716/2.;
+ const Float_t bl1OTTFA = 4.7787/2.;
+ const Float_t tl1OTTFA = 8.4/2.;
+ const Float_t alp1OTTFA = 10.6;
+ const Float_t h2OTTFA = 9.6716/2.;
+ const Float_t bl2OTTFA = 4.7787/2.;
+ const Float_t tl2OTTFA = 8.4/2.;
+ const Float_t alp2OTTFA = 10.6;
+
+// OutTopTrapFrameB Epoxy parameters
+ const Float_t hzOTTFB = hzOuterFrameEpoxy;
+ const Float_t tetOTTFB = 0.;
+ const Float_t phiOTTFB = 0.;
+ const Float_t h1OTTFB = 9.6716/2.;
+ const Float_t bl1OTTFB = 0.;
+ const Float_t tl1OTTFB = 4.7787/2.;
+ const Float_t alp1OTTFB = 13.88;
+ const Float_t h2OTTFB = 9.6716/2.;
+ const Float_t bl2OTTFB = 0.;
+ const Float_t tl2OTTFB = 4.7787/2.;
+ const Float_t alp2OTTFB = 13.88;
+
+ // OutTopTrapFrame Solder parameters
+ const Float_t hzOTTFS = hzOuterFrameSolder;
+
+ // OutTopTrapFrame Inox parameters
+ const Float_t hzOTTFI = hzOuterFrameInox;
+
+/////////////////////////////////////////////////////////
+
+ // OutEdgeTrapFrame parameters
+ // TRAPEZE 1
+ const Float_t hzOETF = hzOuterFrameEpoxy;
+ const Float_t tetOETF = 0.;
+ const Float_t phiOETF = 0.;
+ const Float_t h1OETF = 7.129/2.;
+ const Float_t bl1OETF1 = 3.705/2;
+ const Float_t tl1OETF1 = 3.9471/2.;
+ const Float_t alp1OETF1 = 0.97;
+ const Float_t h2OETF = 7.129/2.;
+ const Float_t bl2OETF1 = 3.705/2;
+ const Float_t tl2OETF1 = 3.9471/2.;
+ const Float_t alp2OETF1 = 0.97;
+
+ // TRAPEZE 2
+ const Float_t bl1OETF2 = 2.9744/2.;
+ const Float_t tl1OETF2 = 3.705/2;
+ const Float_t alp1OETF2 = 2.93;
+
+ const Float_t bl2OETF2 = 2.9744/2.;
+ const Float_t tl2OETF2 = 3.705/2;
+ const Float_t alp2OETF2 = 2.93;
+
+ // TRAPEZE 3
+ const Float_t bl1OETF3 = 1.7455/2.;
+ const Float_t tl1OETF3 = 2.9744/2.;
+ const Float_t alp1OETF3 = 4.93;
+
+ const Float_t bl2OETF3 = 1.7455/2.;
+ const Float_t tl2OETF3 = 2.9744/2.;
+ const Float_t alp2OETF3 = 4.93;
+
+ // TRAPEZE 4
+ const Float_t bl1OETF4 = 0.;
+ const Float_t tl1OETF4 = 1.7455/2.;
+ const Float_t alp1OETF4 = 6.98;
+
+ const Float_t bl2OETF4 = 0.;
+ const Float_t tl2OETF4 = 1.7455/2.;
+ const Float_t alp2OETF4 = 6.98;
+
+ ///////////////////////////////////////////////////
+
+ // OutCornerTrapFrame parameters
+ const Float_t hzOCTF = hzFrameThickness;
+ const Float_t tetOCTF = 0.;
+ const Float_t phiOCTF = 0.;
+ const Float_t h1OCTF = 2.5/2.;
+ const Float_t bl1OCTF = 0.;
+ const Float_t tl1OCTF = 4.7469/2.;
+ const Float_t alp1OCTF = 43.51;
+ const Float_t h2OCTF = 2.5/2.;
+ const Float_t bl2OCTF = 0.;
+ const Float_t tl2OCTF = 4.7469/2.;
+ const Float_t alp2OCTF = 43.51;
+
+ // Reference point - MIRE (3 per quadrant, only 1 programmed)
+ const Float_t MIREInRad = 0.6;
+ const Float_t MIREOutRad = 1.3;
+ const Float_t MIRELen = hzFrameThickness;
+
+ Float_t par[11];
+ Float_t posX,posY,posZ;
+
+// ___________________Make volumes________________________
+
+// Quadrant volume
+ par[0] = fgkMotherIR;
+ par[1] = fgkMotherOR;
+ par[2] = fgkMotherThick;
+ par[3] = fgkMotherPhiL;
+ par[4] = fgkMotherPhiU;
+
+ //Quadrant volume.....positionned at the end
+ gMC->Gsvolu(QuadrantName(chamber),"TUBS",idAir,par,5);
+
+// _______________________________________________________
+// InVFrame
+ if (chamber==1) {
+ // simple epoxy layer...must be inside sensitive surface for tracking
+ par[0] = hxInVFrame;
+ par[1] = hyInVFrame;
+ par[2] = hzInVFrame;
+
+ gMC->Gsvolu("IVEF","BOX",idFrameEpoxy,par,3);
+
+ // InHFrame
+ par[0] = hxInHFrame;
+ par[1] = hyInHFrame;
+ par[2] = hzInHFrame;
+
+ gMC->Gsvolu("IHEF","BOX",idFrameEpoxy,par,3);
+
+ //Flat 1mm vertical section
+ par[0] = hxV1mm;
+ par[1] = hyV1mm;
+ par[2] = hzV1mm;
+
+ gMC->Gsvolu("FVMM","BOX",idFrameEpoxy,par,3);
+
+ //Flat 1mm vertical section
+ par[0] = hxH1mm;
+ par[1] = hyH1mm;
+ par[2] = hzH1mm;
+
+ gMC->Gsvolu("FHMM","BOX",idFrameEpoxy,par,3);
+
+ // OutVFrame
+ par[0] = hxOutVFrame;
+ par[1] = hyOutVFrame;
+ par[2] = hzOutVFrame;
+
+ gMC->Gsvolu("OVEF","BOX",idFrameEpoxy,par,3);
+
+ // InArcFrame
+ par[0] = IAF;
+ par[1] = OAF;
+ par[2] = hzAF;
+ par[3] = AFphi1;
+ par[4] = AFphi2 ;
+
+ gMC->Gsvolu("IAF1","TUBS",idFrameEpoxy,par,5);
+
+ // ScrewsInFrame - 3 sections in order to avoid overlapping volumes
+ // Screw Head, in air
+ par[0] = SCRUHMI;
+ par[1] = SCRUHMA;
+ par[2] = SCRUHLE;
+
+ gMC->Gsvolu("SCRH","TUBE",idInox,par,3);
+
+ // Middle part, in the Epoxy
+ par[0] = SCRUMMI;
+ par[1] = SCRUMMA;
+ par[2] = SCRUMLE;
+
+ gMC->Gsvolu("SCRM","TUBE",idInox,par,3);
+
+ // Screw nut, in air
+ par[0] = SCRUNMI;
+ par[1] = SCRUNMA;
+ par[2] = SCRUNLE;
+
+ gMC->Gsvolu("SCRN","TUBE",idInox,par,3);
+
+ ///////////////////////////////////////////
+
+ // OutTopTrapFrame Epoxy
+ // - 3 components (cuboid and 2 trapezes) and 3 layers (Epoxy/Inox/Solder)
+
+ // OutTopCuboidFrame Epoxy
+ par[0] = hxOutHFrame;
+ par[1] = hyOutHFrame;
+ par[2] = hzOutHFrame;
+
+ gMC->Gsvolu("OHEA","BOX",idFrameEpoxy,par,3);
+
+ // OutTopTrapFrameA Epoxy parameters
+ par[0] = hzOTTFA;
+ par[1] = tetOTTFA;
+ par[2] = phiOTTFA;
+ par[3] = h1OTTFA;
+ par[4] = bl1OTTFA;
+ par[5] = tl1OTTFA;
+ par[6] = alp1OTTFA;
+ par[7] = h2OTTFA;
+ par[8] = bl2OTTFA;
+ par[9] = tl2OTTFA;
+ par[10] = alp2OTTFA;
+
+ gMC->Gsvolu("OHEB","TRAP",idFrameEpoxy,par,11);
+
+ // OutTopTrapFrameB Epoxy parameters
+ par[0] = hzOTTFB;
+ par[1] = tetOTTFB;
+ par[2] = phiOTTFB;
+ par[3] = h1OTTFB;
+ par[4] = bl1OTTFB;
+ par[5] = tl1OTTFB;
+ par[6] = alp1OTTFB;
+ par[7] = h2OTTFB;
+ par[8] = bl2OTTFB;
+ par[9] = tl2OTTFB;
+ par[10] = alp2OTTFB;
+
+ gMC->Gsvolu("OHEC","TRAP",idFrameEpoxy,par,11);
+
+ // OutTopCuboidFrame Solder
+ par[0] = hxOutHFrame;
+ par[1] = hyOutHFrame;
+ par[2] = hzOTTFS;
+ gMC->Gsvolu("OHSA","BOX",idSolder,par,3);
+
+ // OutTopTrapFrameA Solder
+ par[0] = hzOTTFS;
+ par[1] = tetOTTFA;
+ par[2] = phiOTTFA;
+ par[3] = h1OTTFA;
+ par[4] = bl1OTTFA;
+ par[5] = tl1OTTFA;
+ par[6] = alp1OTTFA;
+ par[7] = h2OTTFA;
+ par[8] = bl2OTTFA;
+ par[9] = tl2OTTFA;
+ par[10] = alp2OTTFA;
+
+ gMC->Gsvolu("OHSB","TRAP",idSolder,par,11);
+
+
+ // OutTopTrapFrameB Solder
+ par[0] = hzOTTFI;
+ par[1] = tetOTTFB;
+ par[2] = phiOTTFB;
+ par[3] = h1OTTFB;
+ par[4] = bl1OTTFB;
+ par[5] = tl1OTTFB;
+ par[6] = alp1OTTFB;
+ par[7] = h2OTTFB;
+ par[8] = bl2OTTFB;
+ par[9] = tl2OTTFB;
+ par[10] = alp2OTTFB;
+
+ gMC->Gsvolu("OHSC","TRAP",idSolder,par,11);
+
+ // OutTopCuboidFrame Solder
+ par[0] = hxOutHFrame;
+ par[1] = hyOutHFrame;
+ par[2] = hzOTTFI;
+ gMC->Gsvolu("OHIA","BOX",idInox,par,3);
+
+ // OutTopTrapFrameA Inox
+ par[0] = hzOTTFI;
+ par[1] = tetOTTFA;
+ par[2] = phiOTTFA;
+ par[3] = h1OTTFA;
+ par[4] = bl1OTTFA;
+ par[5] = tl1OTTFA;
+ par[6] = alp1OTTFA;
+ par[7] = h2OTTFA;
+ par[8] = bl2OTTFA;
+ par[9] = tl2OTTFA;
+ par[10] = alp2OTTFA;
+
+ gMC->Gsvolu("OHIB","TRAP",idInox,par,11);
+
+ // OutTopTrapFrameB Inox
+ par[0] = hzOTTFI;
+ par[1] = tetOTTFB;
+ par[2] = phiOTTFB;
+ par[3] = h1OTTFB;
+ par[4] = bl1OTTFB;
+ par[5] = tl1OTTFB;
+ par[6] = alp1OTTFB;
+ par[7] = h2OTTFB;
+ par[8] = bl2OTTFB;
+ par[9] = tl2OTTFB;
+ par[10] = alp2OTTFB;
+
+ gMC->Gsvolu("OHIC","TRAP",idInox,par,11);
+
+ /////////////////////////////////
+
+ // OutEdgeTrapFrame Epoxy = (4 trapezes)*2 copies*3 layers (Epoxy/Inox/Solder)
+ // TRAPEZE 1
+ par[0] = hzOETF;
+ par[1] = tetOETF;
+ par[2] = phiOETF;
+ par[3] = h1OETF;
+ par[4] = bl1OETF1;
+ par[5] = tl1OETF1;
+ par[6] = alp1OETF1;
+ par[7] = h2OETF;
+ par[8] = bl2OETF1;
+ par[9] = tl2OETF1;
+ par[10] = alp2OETF1;
+
+ gMC->Gsvolu("EDE1","TRAP",idFrameEpoxy,par,11);
+
+ // TRAPEZE 2
+ par[4] = bl1OETF2;
+ par[5] = tl1OETF2;
+ par[6] = alp1OETF2;
+
+ par[8] = bl2OETF2;
+ par[9] = tl2OETF2;
+ par[10] = alp2OETF2;
+ gMC->Gsvolu("EDE2","TRAP",idFrameEpoxy,par,11);
+
+ // TRAPEZE 3
+ par[4] = bl1OETF3;
+ par[5] = tl1OETF3;
+ par[6] = alp1OETF3;
+
+ par[8] = bl2OETF3;
+ par[9] = tl2OETF3;
+ par[10] = alp2OETF3;
+ gMC->Gsvolu("EDE3","TRAP",idFrameEpoxy,par,11);
+
+ // TRAPEZE 4
+ par[4] = bl1OETF4;
+ par[5] = tl1OETF4;
+ par[6] = alp1OETF4;
+
+ par[8] = bl2OETF4;
+ par[9] = tl2OETF4;
+ par[10] = alp2OETF4;
+ gMC->Gsvolu("EDE4","TRAP",idFrameEpoxy,par,11);
+
+ ////////////////////////////////
+
+ // TRAPEZE 1
+ par[0] = hzOuterFrameInox;
+ par[1] = tetOETF;
+ par[2] = phiOETF;
+ par[3] = h1OETF;
+ par[4] = bl1OETF1;
+ par[5] = tl1OETF1;
+ par[6] = alp1OETF1;
+ par[7] = h2OETF;
+ par[8] = bl2OETF1;
+ par[9] = tl2OETF1;
+ par[10] = alp2OETF1;
+
+ gMC->Gsvolu("EDI1","TRAP",idInox,par,11);
+
+ // TRAPEZE 2
+ par[4] = bl1OETF2;
+ par[5] = tl1OETF2;
+ par[6] = alp1OETF2;
+
+ par[8] = bl2OETF2;
+ par[9] = tl2OETF2;
+ par[10] = alp2OETF2;
+ gMC->Gsvolu("EDI2","TRAP",idInox,par,11);
+
+ // TRAPEZE 3
+ par[4] = bl1OETF3;
+ par[5] = tl1OETF3;
+ par[6] = alp1OETF3;
+
+ par[8] = bl2OETF3;
+ par[9] = tl2OETF3;
+ par[10] = alp2OETF3;
+ gMC->Gsvolu("EDI3","TRAP",idInox,par,11);
+
+ // TRAPEZE 4
+ par[4] = bl1OETF4;
+ par[5] = tl1OETF4;
+ par[6] = alp1OETF4;
+
+ par[8] = bl2OETF4;
+ par[9] = tl2OETF4;
+ par[10] = alp2OETF4;
+ gMC->Gsvolu("EDI4","TRAP",idInox,par,11);
+
+
+ ////////////////////////////////
+
+ // TRAPEZE 1
+ par[0] = hzOuterFrameSolder;
+ par[1] = tetOETF;
+ par[2] = phiOETF;
+ par[3] = h1OETF;
+ par[4] = bl1OETF1;
+ par[5] = tl1OETF1;
+ par[6] = alp1OETF1;
+ par[7] = h2OETF;
+ par[8] = bl2OETF1;
+ par[9] = tl2OETF1;
+ par[10] = alp2OETF1;
+
+ gMC->Gsvolu("EDS1","TRAP",idSolder,par,11);
+
+ // TRAPEZE 2
+ par[4] = bl1OETF2;
+ par[5] = tl1OETF2;
+ par[6] = alp1OETF2;
+
+ par[8] = bl2OETF2;
+ par[9] = tl2OETF2;
+ par[10] = alp2OETF2;
+ gMC->Gsvolu("EDS2","TRAP",idSolder,par,11);
+
+ // TRAPEZE 3
+ par[4] = bl1OETF3;
+ par[5] = tl1OETF3;
+ par[6] = alp1OETF3;
+
+ par[8] = bl2OETF3;
+ par[9] = tl2OETF3;
+ par[10] = alp2OETF3;
+ gMC->Gsvolu("EDS3","TRAP",idSolder,par,11);
+
+ // TRAPEZE 4
+ par[4] = bl1OETF4;
+ par[5] = tl1OETF4;
+ par[6] = alp1OETF4;
+
+ par[8] = bl2OETF4;
+ par[9] = tl2OETF4;
+ par[10] = alp2OETF4;
+ gMC->Gsvolu("EDS4","TRAP",idSolder,par,11);
+
+ //////////////////////////////////
+
+ // OutCornerTrapFrame
+ par[0] = hzOCTF;
+ par[1] = tetOCTF;
+ par[2] = phiOCTF;
+ par[3] = h1OCTF;
+ par[4] = bl1OCTF;
+ par[5] = tl1OCTF;
+ par[6] = alp1OCTF;
+ par[7] = h2OCTF;
+ par[8] = bl2OCTF;
+ par[9] = tl2OCTF;
+ par[10] = alp2OCTF;
+
+ gMC->Gsvolu("TCOR","TRAP",idFrameEpoxy,par,11);
+
+ // MIRE
+ par[0] = MIREInRad;
+ par[1] = MIREOutRad;
+ par[2] = MIRELen;
+
+ gMC->Gsvolu("MIRE","TUBE",idFrameEpoxy,par,3);
+ }
+
+// __________________Place volumes in the quadrant ____________
+
+ const Float_t BeamOX = 2.6;
+ const Float_t BeamOY = 2.6;
+
+ // Coordinates of the frame corner wrt the beam axis defined at (0,0)
+ Float_t QuadOX = 0.;
+ Float_t QuadOY = 0.;
+
+// InVFrame
+ posX = hxInVFrame;
+ posY = 2.0*hyInHFrame+2.*hyH1mm+IAF+hyInVFrame;
+ posZ = 0.;
+ gMC->Gspos("IVEF",1,QuadrantName(chamber),posX, posY, posZ, 0, "ONLY");
+
+// InHFrame
+ posX = 2.0*hxInVFrame+2.*hxV1mm+IAF+hxInHFrame;
+ posY = hyInHFrame;
+ posZ = 0.;
+ gMC->Gspos("IHEF",1,QuadrantName(chamber),posX, posY, posZ, 0, "ONLY");
+
+// OutVFrame
+ posX = 2.*hxInVFrame+IAF+2.*hxInHFrame-hxOutVFrame+2.*hxV1mm;
+ posY = 2.*hyInHFrame+hyOutVFrame;
+ posZ = 0.;
+ gMC->Gspos("OVEF",1,QuadrantName(chamber),posX, posY, posZ, 0, "ONLY");
+// cout << " Outer vertical frame at " << posX << " " << posY << " "
+// << posZ << " and half length " << hyOutVFrame << endl;
+ const Float_t TOPY = posY+hyOutVFrame;
+ const Float_t OUTX = posX;
+
+//Flat 1mm vertical section
+ posX = 2.0*hxInVFrame+hxV1mm;
+ posY = 2.0*hyInHFrame+2.*hyH1mm+IAF+hyV1mm;
+ posZ = 0.;
+ gMC->Gspos("FVMM",1,QuadrantName(chamber),posX, posY, posZ,0, "ONLY");
+
+// Flat 1mm horizontal section
+ posX = 2.0*hxInVFrame+2.*hxV1mm+IAF+hxH1mm;
+ posY = 2.0*hyInHFrame+hyH1mm;
+ posZ = 0.;
+ gMC->Gspos("FHMM",1,QuadrantName(chamber),posX, posY, posZ,0, "ONLY");
+
+// InArcFrame
+ posX = 2.0*hxInVFrame+2.*hxV1mm;
+ posY = 2.0*hyInHFrame+2.*hyH1mm;
+ posZ = 0.;
+ gMC->Gspos("IAF1",1,QuadrantName(chamber),posX, posY, posZ,0, "ONLY");
+
+
+// ScrewsInFrame
+
+// Only place screws that are inside the sensitive volume.
+
+ Float_t scruX[64];
+ Float_t scruY[64];
+
+// Screws on IHEpoxyFrame
+
+ const Int_t NumberOfScrewsIH = 14; // no. of screws on the IHEpoxyFrame
+ const Float_t offX = 5.; // inter-screw distance
+
+ // first screw coordinates
+ scruX[0] = 21.07;
+ scruY[0] = -2.23;
+ // other screw coordinates
+ for (Int_t i = 1;i<NumberOfScrewsIH;i++){
+ scruX[i] = scruX[i-1]+offX;
+ scruY[i] = scruY[0];
+ }
+ // Position the volumes on the frames
+ for (Int_t i = 0;i<NumberOfScrewsIH;i++){
+ posX = BeamOX + scruX[i];
+ posY = BeamOY + scruY[i];
+ posZ = 0.;
+ gMC->Gspos("SCRH",i+1,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ-hzInHFrame-SCRUHLE, 0, "ONLY");
+ gMC->Gspos("SCRM",i+1,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ, 0, "ONLY");
+ gMC->Gspos("SCRN",i+1,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ+hzInHFrame+SCRUNLE, 0, "ONLY");
+ }
+ // special screw coordinates
+ scruX[63] = 16.3;
+ scruY[63] = -2.23;
+ posX = BeamOX + scruX[63];
+ posY = BeamOY + scruY[63];
+ posZ = 0.;
+ gMC->Gspos("SCRH",64,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ-hzInHFrame-SCRUHLE, 0, "ONLY");
+ gMC->Gspos("SCRM",64,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ, 0, "ONLY");
+ gMC->Gspos("SCRN",64,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ+hzInHFrame+SCRUNLE, 0, "ONLY");
+
+// Screws on the IVEpoxyFrame
+
+ const Int_t NumberOfScrewsIV = 15; // no. of screws on the IVEpoxyFrame
+ const Float_t offY = 5.; // inter-screw distance
+ Int_t FirstScrew = 58;
+ Int_t LastScrew = 44;
+
+ // first (special) screw coordinates
+ scruX[FirstScrew-1] = -2.23;
+ scruY[FirstScrew-1] = 16.3;
+ // second (repetitive) screw coordinates
+ scruX[FirstScrew-2] = -2.23;
+ scruY[FirstScrew-2] = 21.07;
+ // other screw coordinates
+ for (Int_t i = FirstScrew-3;i>LastScrew-2;i--){
+ scruX[i] = scruX[FirstScrew-2];
+ scruY[i] = scruY[i+1]+offY;
+ }
+
+ for (Int_t i = 0;i<NumberOfScrewsIV;i++){
+ posX = BeamOX + scruX[i+LastScrew-1];
+ posY = BeamOY + scruY[i+LastScrew-1];
+ posZ = 0.;
+ gMC->Gspos("SCRH",i+LastScrew,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ-hzInHFrame-SCRUHLE, 0, "ONLY");
+ gMC->Gspos("SCRM",i+LastScrew,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ, 0, "ONLY");
+ gMC->Gspos("SCRN",i+LastScrew,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ+hzInHFrame+SCRUNLE, 0, "ONLY");
+ }
+
+// Screws on the OVEpoxyFrame
+
+ const Int_t NumberOfScrewsOV = 10; // no. of screws on the OVEpoxyFrame
+
+ FirstScrew = 15;
+ LastScrew = 25;
+
+ // first (repetitive) screw coordinates
+ scruX[FirstScrew-1] = 90.9;
+ scruY[FirstScrew-1] = -2.23; // true value
+
+ // other screw coordinates
+ for (Int_t i = FirstScrew; i<LastScrew; i++ ){
+ scruX[i] = scruX[FirstScrew-1];
+ scruY[i] = scruY[i-1]+offY;
+ }
+ for (Int_t i = 0;i<NumberOfScrewsOV;i++){
+ posX = BeamOX + scruX[i+FirstScrew-1];
+ posY = BeamOY + scruY[i+FirstScrew-1];
+ posZ = 0.;
+ gMC->Gspos("SCRH",i+FirstScrew,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ-hzInHFrame-SCRUHLE, 0, "ONLY");
+ gMC->Gspos("SCRM",i+FirstScrew,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ, 0, "ONLY");
+ gMC->Gspos("SCRN",i+FirstScrew,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ+hzInHFrame+SCRUNLE, 0, "ONLY");
+ }
+
+// Inner Arc of Frame, screw positions and numbers-1
+ scruX[62] = 16.009; scruY[62] = 1.401;
+ scruX[61] = 14.564; scruY[61] = 6.791;
+ scruX[60] = 11.363; scruY[60] = 11.363;
+ scruX[59] = 6.791 ; scruY[59] = 14.564;
+ scruX[58] = 1.401 ; scruY[58] = 16.009;
+
+ for (Int_t i = 0;i<5;i++){
+ posX = BeamOX + scruX[i+58];
+ posY = BeamOY + scruY[i+58];
+ posZ = 0.;
+ gMC->Gspos("SCRH",i+58+1,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ-hzInHFrame-SCRUHLE, 0, "ONLY");
+ gMC->Gspos("SCRM",i+58+1,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ, 0, "ONLY");
+ gMC->Gspos("SCRN",i+58+1,QuadrantName(chamber),posX-QuadOX+0.1, posY-QuadOY+0.1, posZ+hzInHFrame+SCRUNLE, 0, "ONLY");
+ }
+
+// OutTopTrapFrame
+ posX = hxOutHFrame;
+ posY = 2.*hyInHFrame+IAF+2.*hyInVFrame+hyOutHFrame+2.*hyH1mm;
+ posZ = 0.;
+
+// place 3 layers of cuboids
+ posZ = posZ-(hzOuterFrameSolder+hzOuterFrameInox);
+ gMC->Gspos("OHEA",1,QuadrantName(chamber),posX, posY, posZ,0,"ONLY");
+ posZ = posZ+hzOuterFrameInox+hzOuterFrameSolder;
+ gMC->Gspos("OHSA",1,QuadrantName(chamber),posX, posY, posZ,0,"ONLY");
+ posZ = posZ+hzOuterFrameSolder+hzOuterFrameInox;
+ gMC->Gspos("OHIA",1,QuadrantName(chamber),posX, posY, posZ,0,"ONLY");
+
+// place 3 layers of trapezoid A
+ posX = 34.1663+2.6;
+ posY = 92.2946+2.6;
+ posZ = 0.;
+
+ posZ = posZ-(hzOuterFrameSolder+hzOuterFrameInox);
+ gMC->Gspos("OHEB",1,QuadrantName(chamber),posX, posY, posZ, idrotm[1102],"ONLY");
+ posZ = posZ+hzOuterFrameInox+hzOuterFrameSolder;
+ gMC->Gspos("OHSB",1,QuadrantName(chamber),posX, posY, posZ, idrotm[1102],"ONLY");
+ posZ = posZ+hzOuterFrameSolder+hzOuterFrameInox;
+ gMC->Gspos("OHIB",1,QuadrantName(chamber),posX, posY, posZ, idrotm[1102],"ONLY");
+
+// place 3 layers of trapezoid B
+ posX = 43.8379+2.6;
+ posY = 90.1946+2.6;
+ posZ = 0.;
+
+ posZ = posZ-(hzOuterFrameSolder+hzOuterFrameInox);
+ gMC->Gspos("OHEC",1,QuadrantName(chamber),posX, posY, posZ, idrotm[1102],"ONLY");
+ posZ = posZ+hzOuterFrameInox+hzOuterFrameSolder;
+ gMC->Gspos("OHSC",1,QuadrantName(chamber),posX, posY, posZ, idrotm[1102],"ONLY");
+ posZ = posZ+hzOuterFrameSolder+hzOuterFrameInox;
+ gMC->Gspos("OHIC",1,QuadrantName(chamber),posX, posY, posZ, idrotm[1102],"ONLY");
+
+///////////////////////////////////////////////////
+
+// OutEdgeTrapFrame
+
+ const Float_t refY = 70.13685;
+ const Float_t refX = 71.43685;
+
+ posX = refX;
+ posY = refY;
+ posZ = 0.;
+
+ Float_t XCenter[8];
+ Float_t YCenter[8];
+
+ XCenter[0] = 72.7099 + 2.6;
+ XCenter[1] = 77.5787 + 2.6;
+ XCenter[2] = 82.2732 + 2.6;
+ XCenter[3] = 86.7882 + 2.6;
+
+ YCenter[0] = 67.6691 + 2.6;
+ YCenter[1] = 62.4564 + 2.6;
+ YCenter[2] = 57.0693 + 2.6;
+ YCenter[3] = 51.5027 + 2.6;
+
+ XCenter[4] = 67.6691 + 2.6;
+ XCenter[5] = 62.4564 + 2.6;
+ XCenter[6] = 57.0693 + 2.6;
+ XCenter[7] = 51.5027 + 2.6;
+
+ YCenter[4] = 72.7099 + 2.6;
+ YCenter[5] = 77.5787 + 2.6;
+ YCenter[6] = 82.2732 + 2.6;
+ YCenter[7] = 86.7882 + 2.6;
+
+ posZ = posZ-(hzOuterFrameSolder+hzOuterFrameInox);
+ gMC->Gspos("EDE1",1,QuadrantName(chamber), XCenter[0], YCenter[0], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDE1",2,QuadrantName(chamber), XCenter[4], YCenter[4],posZ, idrotm[1105],"ONLY");
+
+
+ gMC->Gspos("EDE2",1,QuadrantName(chamber), XCenter[1], YCenter[1], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDE2",2,QuadrantName(chamber), XCenter[5], YCenter[5], posZ, idrotm[1105],"ONLY");
+
+ gMC->Gspos("EDE3",1,QuadrantName(chamber), XCenter[2], YCenter[2], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDE3",2,QuadrantName(chamber), XCenter[6], YCenter[6], posZ, idrotm[1105],"ONLY");
+
+
+ gMC->Gspos("EDE4",1,QuadrantName(chamber), XCenter[3], YCenter[3], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDE4",2,QuadrantName(chamber), XCenter[7], YCenter[7], posZ, idrotm[1105],"ONLY");
+
+
+
+ posZ = posZ+hzOuterFrameEpoxy+hzOuterFrameInox;
+
+ gMC->Gspos("EDI1",1,QuadrantName(chamber), XCenter[0], YCenter[0], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDI1",2,QuadrantName(chamber), XCenter[4], YCenter[4], posZ, idrotm[1105],"ONLY");
+
+ gMC->Gspos("EDI2",1,QuadrantName(chamber), XCenter[1], YCenter[1], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDI2",2,QuadrantName(chamber), XCenter[5], YCenter[5], posZ, idrotm[1105],"ONLY");
+
+ gMC->Gspos("EDI3",1,QuadrantName(chamber), XCenter[2], YCenter[2], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDI3",2,QuadrantName(chamber), XCenter[6], YCenter[6], posZ, idrotm[1105],"ONLY");
+
+ gMC->Gspos("EDI4",1,QuadrantName(chamber), XCenter[3], YCenter[3], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDI4",2,QuadrantName(chamber), XCenter[7], YCenter[7], posZ, idrotm[1105],"ONLY");
+
+
+ posZ = posZ+hzOuterFrameInox+hzOuterFrameSolder;
+
+ gMC->Gspos("EDS1",1,QuadrantName(chamber), XCenter[0], YCenter[0], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDS1",2,QuadrantName(chamber), XCenter[4], YCenter[4], posZ, idrotm[1105],"ONLY");
+
+ gMC->Gspos("EDS2",1,QuadrantName(chamber), XCenter[1], YCenter[1], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDS2",2,QuadrantName(chamber), XCenter[5], YCenter[5], posZ, idrotm[1105],"ONLY");
+
+ gMC->Gspos("EDS3",1,QuadrantName(chamber), XCenter[2], YCenter[2], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDS3",2,QuadrantName(chamber), XCenter[6], YCenter[6], posZ, idrotm[1105],"ONLY");
+
+ gMC->Gspos("EDS4",1,QuadrantName(chamber), XCenter[3], YCenter[3], posZ, idrotm[1104],"ONLY");
+ gMC->Gspos("EDS4",2,QuadrantName(chamber), XCenter[7], YCenter[7], posZ, idrotm[1105],"ONLY");
+
+
+// OutCornerTrapFrame
+ posX = OUTX;
+ posY = TOPY+((bl1OCTF+tl1OCTF)/2.);
+ posZ = 0.;
+ gMC->Gspos("TCOR",1,QuadrantName(chamber),posX, posY, posZ, idrotm[1102],"ONLY");
+
+// Mire placement
+ posX = OUTX+hxOutVFrame+1.3;
+ posY = 8.13+2.6;
+ posZ = 0.;
+ gMC->Gspos("MIRE",1,QuadrantName(chamber),posX, posY, posZ, 0,"ONLY");
+
+}
+
+//___________________________________________
+void AliMUONv2::CreateHole()
+{
+// Create all the element inside a foam hole
+// --
+ Int_t* idtmed = fIdtmed->GetArray()-1099;
+ Int_t idAir = idtmed[1100]; // medium 1
+ Int_t idCopper = idtmed[1109]; // medium 10 = copper
+
+ GReal_t par[3];
+ GReal_t posX,posY,posZ;
+
+ par[0] = fgkHxHole;
+ par[1] = fgkHyHole;
+ par[2] = fgkHzFoam;
+ gMC->Gsvolu(fgkHoleName,"BOX",idAir,par,3);
+
+ par[0] = fgkHxKapton;
+ par[1] = fgkHyKapton;
+ par[2] = fgkHzSnPb;
+ gMC->Gsvolu("SNPB", "BOX", idCopper, par, 3);
+ posX = 0.;
+ posY = 0.;
+ posZ = -fgkHzFoam+fgkHzSnPb;
+ gMC->Gspos("SNPB",1,fgkHoleName, posX, posY, posZ, 0,"ONLY");
+
+ par[0] = fgkHxHole;
+ par[1] = fgkHyBergPlastic;
+ par[2] = fgkHzKapton;
+ gMC->Gsvolu("KAPT", "BOX", idCopper, par, 3);
+ posX = 0.;
+ posY = 0.;
+ posZ = 0.;
+ gMC->Gspos("KAPT",1,fgkHoleName, posX, posY, posZ, 0,"ONLY");
+}
+
+//___________________________________________
+void AliMUONv2::CreateDaughterBoard()
+{
+// Create all the elements in a daughter board
+// --
+ Int_t* idtmed = fIdtmed->GetArray()-1099;
+ Int_t idAir = idtmed[1100]; // medium 1
+ Int_t idCopper = idtmed[1109]; // medium 10 = copper
+ Int_t idPlastic =idtmed[1116]; // medium 17 = Plastic
+
+ GReal_t par[3];
+ GReal_t posX,posY,posZ;
+
+ par[0]=fgkHxDaughter;
+ par[1]=fgkHyDaughter;
+ par[2]=totalHzDaughter();
+ gMC->Gsvolu(fgkDaughterName,"BOX",idAir,par,3);
+
+ par[0]=fgkHxBergPlastic;
+ par[1]=fgkHyBergPlastic;
+ par[2]=fgkHzBergPlastic;
+ gMC->Gsvolu("BRGP","BOX",idPlastic,par,3);
+ posX=0.;
+ posY=0.;
+ posZ = -totalHzDaughter() + fgkHzBergPlastic;
+ gMC->Gspos("BRGP",1,fgkDaughterName,posX,posY,posZ,0,"ONLY");
+
+ par[0]=fgkHxBergCopper;
+ par[1]=fgkHyBergCopper;
+ par[2]=fgkHzBergCopper;
+ gMC->Gsvolu("BRGC","BOX",idCopper,par,3);
+ posX=0.;
+ posY=0.;
+ posZ=0.;
+ gMC->Gspos("BRGC",1,"BRGC",posX,posY,posZ,0,"ONLY");
+
+ par[0]=fgkHxDaughter;
+ par[1]=fgkHyDaughter;
+ par[2]=fgkHzDaughter;
+ gMC->Gsvolu("DGHT","BOX",idCopper,par,3);
+ posX=0.;
+ posY=0.;
+ posZ = -totalHzDaughter() + 2.*fgkHzBergPlastic + fgkHzDaughter;
+ gMC->Gspos("DGHT",1,fgkDaughterName,posX,posY,posZ,0,"ONLY");
+}
+
+//___________________________________________
+void AliMUONv2::CreatePlaneBox(const char* name,const TVector2& dimensions)
+{
+// create all the elements in the copper plane
+// --
+ Int_t* idtmed = fIdtmed->GetArray()-1099;
+ Int_t idAir = idtmed[1100]; // medium 1
+ Int_t idCopper = idtmed[1109]; // medium 10 = copper
+ Int_t idFoam = idtmed[1115]; // medium 16 = Foam
+ Int_t idFR4 =idtmed[1114]; // medium 15 = FR4
+
+ GReal_t par[3];
+ GReal_t posX,posY,posZ;
+
+ // mother volume
+ par[0] = dimensions.X();
+ par[1] = dimensions.Y();
+ par[2] = totalHzPlane();
+ gMC->Gsvolu(name,"BOX",idAir,par,3);
+
+ // pad plane
+ char* planeName = strdup(name);
+ planeName[3]='P';
+ par[0] = dimensions.X();
+ par[1] = dimensions.Y();
+ par[2] = fgkHzPadPlane;
+ gMC->Gsvolu(planeName,"BOX",idCopper,par,3);
+ posX=0.;
+ posY=0.;
+ posZ = -totalHzPlane()+fgkHzPadPlane;
+ gMC->Gspos(planeName,1,name,posX,posY,posZ,0,"ONLY");
+
+ //foam layer
+ char* foamName = strdup(name);
+ foamName[3]=fgkFoamLayerSuffix;
+ par[0] = dimensions.X();
+ par[1] = dimensions.Y();
+ par[2] = fgkHzFoam;
+ gMC->Gsvolu(foamName,"BOX",idFoam,par,3);
+ posX=0.;
+ posY=0.;
+ posZ = -totalHzPlane()+2.*fgkHzPadPlane+fgkHzFoam;
+ gMC->Gspos(foamName,1,name,posX,posY,posZ,0,"ONLY");
+
+ // mechanical plane FR4 layer
+ char* fr4Name = strdup(name);
+ fr4Name[3]='R';
+ par[0] = dimensions.X();
+ par[1] = dimensions.Y();
+ par[2] = fgkHzFR4;
+ gMC->Gsvolu(fr4Name,"BOX",idFR4,par,3);
+ posX=0.;
+ posY=0.;
+ posZ = -totalHzPlane()+2.*fgkHzPadPlane+2.*fgkHzFoam+fgkHzFR4;
+ gMC->Gspos(fr4Name,1,name,posX,posY,posZ,0,"ONLY");
+}
+
+//___________________________________________
+void AliMUONv2::CreatePlaneSegment(const char* name,const TVector2& dimensions
+ ,Int_t nofHoles)
+{
+// Create a segment of a plane (this includes a copper layer, foam, hole,
+// and kapton as well as the mother board.)
+// --
+ static Int_t holeNum=1;
+
+ GReal_t posX,posY,posZ;
+
+ CreatePlaneBox(name,dimensions);
+ char holeName[5];
+ strcpy(holeName,name);
+ holeName[3]=fgkFoamLayerSuffix;
+ // <dname> is a motif on the pad plane
+ char* dname = strdup(name);
+ dname[3]='D';
+ gMC->Gsdvn(dname,holeName,nofHoles,1);
+
+ posX=0.;
+ posY=0.;
+ posZ= fgkHzPadPlane;
+ gMC->Gspos(fgkHoleName,holeNum++,dname,posX,posY,posZ,0,"ONLY");
+}
+
+//___________________________________________
+void AliMUONv2::CreateDaughterSegment(const char* name,const TVector2& dimensions,
+ Int_t nofHoles)
+{
+// Create a segment of a daughter board layer
+// --
+ static Int_t holeNum=1;
+ Int_t* idtmed = fIdtmed->GetArray()-1099;
+ Int_t idAir = idtmed[1100]; // medium 1
+
+ GReal_t par[3];
+ GReal_t posX,posY,posZ;
+
+ par[0] = dimensions.X();
+ par[1] = dimensions.Y();
+ par[2] = totalHzDaughter();
+ gMC->Gsvolu(name,"BOX",idAir,par,3);
+
+ // <dname> is a motif on pad plane
+ char* dname = strdup(name);
+ dname[3]='D';
+ gMC->Gsdvn(dname,name,nofHoles,1);
+
+ posX=0.;
+ posY=0.;
+ posZ=0.;
+ gMC->Gspos(fgkDaughterName,holeNum++,dname,posX,posY,posZ,0,"ONLY");
+}
+
+//___________________________________________
+void AliMUONv2::PlaceSector(MSector* sector,TSpecialMap specialMap
+ ,const TVector3& where,Int_t chamber)
+{
+// Place all the segments in the mother volume, in the position defined
+// by the sector's data.
+// --
+ static Int_t segNum=1;
+
+ GReal_t posX,posY,posZ;
+
+ vector<int> already_done;
+ Int_t rotNum;
+ AliMatrix(rotNum, 90.,90.,90,180.,0.,0.);
+
+ for (Int_t irow=0;irow<sector->GetNofRows();irow++){
+ MRow* row = sector->GetRow(irow);
+ for (Int_t iseg=0;iseg<row->GetNofRowSegments();iseg++){
+ MVRowSegment* seg = row->GetRowSegment(iseg);
+ char* segName;
+
+ TSpecialMap::iterator iter
+ = specialMap.find(seg->GetMotifPositionId(0));
+ if ( iter == specialMap.end()){
+ segName = strdup(Form("%.3dM",segNum*2));
+ CreatePlaneSegment(segName,seg->Dimensions()/10.,seg->GetNofMotifs());
+ posX = where.X()+seg->Position().X()/10.-fgkOffsetX/2.;
+ posY = where.Y()+seg->Position().Y()/10.-fgkOffsetY/2.;
+ posZ = where.Z()-totalHz()+totalHzPlane();
+ gMC->Gspos(segName,1,QuadrantName(chamber),posX,posY,posZ,0,"ONLY");
+
+ segName = strdup(Form("%.3dM",segNum*2+1));
+ CreateDaughterSegment(segName,seg->Dimensions()/10.,seg->GetNofMotifs());
+ posX = where.X()+seg->Position().X()/10.+fgkOffsetX/2.;
+ posY = where.Y()+seg->Position().Y()/10.-+fgkOffsetY/2.;
+ posZ = where.Z()-totalHz()+2.*totalHzPlane()+totalHzDaughter();
+ gMC->Gspos(segName,1,QuadrantName(chamber),posX,posY,posZ,0,"ONLY");
+ segNum++;
+ } else {
+ for (Int_t motifNum=0;motifNum<seg->GetNofMotifs();motifNum++) {
+ Int_t motifPosId = seg->GetMotifPositionId(motifNum);
+
+ if (find(already_done.begin(),already_done.end(),motifPosId)
+ != already_done.end()) continue;
+
+ AliMUONSt1SpecialMotif spMot = specialMap[motifPosId];
+
+ MMotifPosition* motifPos =
+ sector->GetMotifMap()->FindMotifPosition(motifPosId);
+ MMotifType* mType = motifPos->GetMotif()->GetMotifType();
+ for (Int_t line=0;line<mType->GetNofPadsY();line++) {
+ Int_t iMin=-1,iMax=-1,col;
+ for (col=0;col<mType->GetNofPadsX();col++) {
+ if (mType->HasPad(MIntPair(col,line))) {
+ iMin=col;
+ break;
+ }
+ }
+ for (col=mType->GetNofPadsX()-1;col>=0;col--) {
+ if (mType->HasPad(MIntPair(col,line))) {
+ iMax=col;
+ break;
+ }
+ }
+ if ( (iMin>=0) && (iMax>=0) ) {
+ TVector2 dim =
+ motifPos->GetMotif()->GetPadDimensions(MIntPair(iMin,line))/10.;
+ TVector2 lineDim(dim.X()*(iMax-iMin+1),dim.Y());
+ char* boxName = strdup(Form("%.3dM",segNum*2));
+ CreatePlaneBox(boxName,lineDim);
+ TVector2 posLLline = TVector2(dim.X()*2.*iMin,dim.Y()*2.*line)
+ +motifPos->Position()/10.-motifPos->Dimensions()/10.;
+ TVector2 centerLine = posLLline + lineDim;
+ posX = where.X()+centerLine.X()-fgkOffsetX/2.;
+ posY = where.Y()+centerLine.Y()-fgkOffsetY/2.;
+ posZ = where.Z()-totalHz()+totalHzPlane();
+ gMC->Gspos(boxName,1,QuadrantName(chamber),posX,posY,posZ,0,"ONLY");
+ }
+
+ segNum++;
+ }
+
+ Int_t rot = ( spMot.GetRotAngle()<0.1 ) ? 0:rotNum;
+
+ posX = where.X()+motifPos->Position().X()/10.-fgkOffsetX/2.+spMot.GetDelta().X();
+ posY = where.Y()+motifPos->Position().Y()/10.-fgkOffsetY/2.+spMot.GetDelta().Y();
+ posZ = where.Z()-fgkHzPadPlane;
+ gMC->Gspos(fgkHoleName,motifPosId,QuadrantName(chamber),posX,posY,posZ,rot,"ONLY");
+
+ posX = where.X()+motifPos->Position().X()/10.+fgkOffsetX/2.-fgkDeltaFilleEtamX+spMot.GetDelta().X();
+ posY = where.Y()+motifPos->Position().Y()/10.-+fgkOffsetY/2.-fgkDeltaFilleEtamY+spMot.GetDelta().Y();
+ posZ = where.Z()-totalHz()+2.*totalHzPlane()+totalHzDaughter();
+ gMC->Gspos(fgkDaughterName,motifPosId,QuadrantName(chamber),posX,posY,posZ,rot,"ONLY");
+
+ already_done.push_back(motifPosId);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+#ifndef ALI_MUON_V2_H
+#define ALI_MUON_V2_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
+//
+// Class AliMUONv2
+// ---------------
+// Inherits from AliMUONv1 but with a more detailed
+// geometrical description of station 1
+
+#include <map>
+
+#include "AliMUONv1.h"
+#include "AliMUONSt1SpecialMotif.h"
+
+#include <TVector2.h>
+#include <TVector3.h>
+
+typedef Float_t GReal_t; // for AliGeant3
+//typedef Double_t GReal_t; // for VirtualMC
+
+class TTree;
+class MSector;
+using std::map;
+
+
+class AliMUONv2 : public AliMUONv1 {
+ public:
+ AliMUONv2();
+ AliMUONv2(const char* name, const char* title);
+ AliMUONv2(const AliMUONv2& rMUON);
+ virtual ~AliMUONv2();
+
+ virtual Int_t IsVersion() const;
+ virtual void CreateGeometry();
+ virtual void CreateMaterials();
+
+ protected:
+ // Copy Operator
+ AliMUONv2& operator = (const AliMUONv2& rhs);
+
+ private:
+
+ typedef map< Int_t , AliMUONSt1SpecialMotif > TSpecialMap;
+ static const GReal_t fgkHzPadPlane; // Pad plane
+ static const GReal_t fgkHzFoam; // Foam of mechanicalplane
+ static const GReal_t fgkHzFR4; // FR4 of mechanical plane
+ static const GReal_t fgkHzSnPb; //Pad/Kapton connection (66 pt)
+ static const GReal_t fgkHzKapton; //Kapton
+ static const GReal_t fgkHzBergPlastic; //Berg connector
+ static const GReal_t fgkHzBergCopper; //Berg connector (80 pt)
+ static const GReal_t fgkHzDaughter; //Daughter board
+ static const GReal_t fgkHzGas ; // ArCO2 Gas
+
+ GReal_t totalHzPlane() const ; //Total mechanical plane half Size
+ GReal_t totalHzDaughter() const ; //Total daughter plane half Size
+ GReal_t totalHz() const ; //Total plane half Size
+
+ static const GReal_t fgkHxHole;
+ static const GReal_t fgkHyHole;
+ static const GReal_t fgkHxBergPlastic;
+ static const GReal_t fgkHyBergPlastic;
+ static const GReal_t fgkHxBergCopper;
+ static const GReal_t fgkHyBergCopper;
+ static const GReal_t fgkHxKapton;
+ static const GReal_t fgkHyKapton;
+ static const GReal_t fgkHxDaughter;
+ static const GReal_t fgkHyDaughter;
+ static const GReal_t fgkOffsetX;
+ static const GReal_t fgkOffsetY;
+ static const GReal_t fgkDeltaFilleEtamX;
+ static const GReal_t fgkDeltaFilleEtamY;
+ static const GReal_t fgkHxQuadrant;
+ static const GReal_t fgkHyQuadrant;
+ static const GReal_t fgkMotherIR;
+ static const GReal_t fgkMotherOR;
+ static const GReal_t fgkMotherThick;
+ static const GReal_t fgkMotherPhiL;
+ static const GReal_t fgkMotherPhiU;
+
+ static const char* fgkHoleName;
+ static const char* fgkQuadrantName;
+ static const char* fgkDaughterName;
+ static const char fgkFoamLayerSuffix;
+
+
+ void CreateHole();
+ void CreateDaughterBoard();
+ void CreateFrame(Int_t chamber);
+ void CreateQuadrant(Int_t chamber);
+ void CreatePlaneBox(const char* name,const TVector2& dimensions);
+ void CreatePlaneSegment(const char* name,const TVector2& dimensions
+ ,Int_t nofHoles);
+ void CreateDaughterSegment(const char* name,const TVector2& dimensions
+ ,Int_t nofHoles);
+ void PlaceSector(MSector* sector,TSpecialMap specialMap
+ ,const TVector3& where,Int_t chamber);
+ TString QuadrantName(Int_t chamber);
+ Int_t fIdSens; // Sensitive volume identifier
+
+
+ ClassDef(AliMUONv2,1) // MUON Detector base class
+};
+
+// inline functions
+
+inline Int_t AliMUONv2::IsVersion () const
+ { return 2; }
+inline GReal_t AliMUONv2::totalHzPlane() const
+ { return fgkHzPadPlane + fgkHzFoam + fgkHzFR4;}
+inline GReal_t AliMUONv2::totalHzDaughter() const
+ { return fgkHzBergPlastic + fgkHzDaughter;}
+inline GReal_t AliMUONv2::totalHz() const
+ { return totalHzPlane() + totalHzDaughter();}
+inline TString AliMUONv2::QuadrantName(Int_t chamber)
+{return Form("%s%d",fgkQuadrantName,chamber);}
+
+
+#endif //ALI_MUON_V2_H
#pragma link C++ class AliMUONTrackK+;
#pragma link C++ class AliMUONPixel+;
#pragma link C++ class AliMUONClusterFinderAZ+;
+
+#ifdef USE_MUON_MAPPING
+#pragma link C++ class AliMUONv2+;
+#pragma link C++ class AliMUONSt1Segmentation+;
+#pragma link C++ class AliMUONSt1Response+;
+#pragma link C++ class AliMUONSt1ElectronicElement+;
+#pragma link C++ class AliMUONSt1SpecialMotif+;
+#pragma link C++ class AliMUONSt1ResponseParameter+;
+#pragma link C++ class AliMUONSt1ResponseRule+;
+#endif
+
#endif